Performing a search in String[][] - java

Give a two-dimensional array T with base type String and some string str (which can be treated like an array of type String) I want to check if T contains certain parts str as its entries. I tried this:
int indeksck = str.indexOf("C");
while(k<T.length){
if(T[k][2] == str.substring(indeksck+1)){
if(T[k][1] == str.substring(6, indeksck)){
int ile_o = Integer.parseInt(T[k][0]);
T[k][0]= Integer.toString(ile_o+1);
T[k][3] = T[k][3]+"X"+str.substring(1,6);
k = T.length+1;
} else {
k++;
}
} else {
k++;
if(k==T.length){
k = 0;
while(k<T.length){
if(T[k][0]==null){
T[k][0] = Integer.toString(1);
T[k][1] = str.substring(6,indeksck);
T[k][2] = str.substring(indeksck+1);
T[k][3] = str.substring(1,6);
k = T.length+1;
} else {
k++;
}
}
}
}
}
The problem is that the first part of my code is being ignored (even when condition should be satisfied). I would appreciate and suggestions on solving this problem.

You cannot use == to do string compare. Try:
if(T[k][2].equals(str.substring(indeksck+1))) {

== operator in Java is used for reference comparison. To check equivalence for objects (so also for strings) you need to use equals() method.

Related

How to work around a NullPointerException in Java?

So I have a text file that contains a bunch of strings that I import into the program and what my program does is look for the first index of the first duplicate string:
static final int NOT_FOUND = -1;
dupeIndex = indexOfFirstDupe( wordList, wordCount );
if ( dupeIndex == NOT_FOUND )
System.out.format("No duplicate values found in wordList\n");
else
System.out.format("First duplicate value in wordList found at index %d\n",dupeIndex);
and the method I use to find the first index of the duplicate is as follows:
static int indexOfFirstDupe( String[] arr, int count )
{
Arrays.sort(arr);
int size = arr.length;
int index = NOT_FOUND;
for (int x = 0; x < size; x++) {
for (int y = x + 1; y < size; y++) {
if (arr[x].equals(arr[y])) {
index = x;
break;
}
}
}
return index;
The problem is that I get this error:
It's a NullPointerException and from my understanding it means that there's basically a null value(s) in my array of strings(?). Is there any simple solution to this that I am missing? Possibly rewording my method?
The error is caused by Array.sort(arr);
According to Java doc (https://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html#sort-java.lang.Object%3aA-):
Sorts the specified array of objects into ascending order, according to the natural ordering of its elements. All elements in the array must implement the Comparable interface.
It is very likely that the exception was thrown when the sort tries to call the compareTo method on the null objects of the String array.
So one simple direct solution is to make sure no null objects in your String array...
There is a better way to do what you want to do.
This is complexity O(n) vs yours is O(n^2) + failing sort.
public int indexOfFirstDup(String[] arr) {
Set<String> valuesFound = new HashSet<>();
for (int i=0;i<arr.length; i++) {
String s = arr[i];
// ignore nulls
if (s == null) { continue; }
if (valuesFound.contains(s)) {
// here we identified a duplication and we can leave
return i;
} else {
valuesFound.add(s);
}
}
// no dups
return -1;
}
NOTE the code has not been compiled nor tested - its just an idea!
Assuming that you are correct in your diagnosis
... it means that there's basically a null value(s) in my array of strings ...
... I can think of two workarounds.
Get rid of the null references in the array. Remove them entirely, or replace them with (say) "" or "null" or something else harmless.
There is an overload of the Arrays.sort method that takes a second argument: a Comparator. So what you could do is to implement a Comparator that can handle null without throwing an NPE. (For example, it could treat null as smaller than all non-null strings.)
Here's an example comparator that deals with null:
public class NullSafeStringComparator implements Comparator<String> {
public int compare(String s1, String s2) {
if (s1 == s2) {
return 0;
} else if (s1 == null) {
return -1;
} else if (s2 == null) {
return 1;
} else {
return s1.compareTo(s2);
}
}
}
Alternatively, for Java 8 and later you can build one as follows:
Comparator.nullsFirst(Comparator.naturalOrder())

Error: bad operand types for binary operator '+'

I have here a code that would take a String called toRepeat and repeat it in the same line by n number of times. For example toRepeat = *, n= 3, result = ***
public class RepeatIt {
public static String repeatString(final Object toRepeat, final int n) {
int i = 0;
if (toRepeat instanceof String) {
while (i < n) {
toRepeat = toRepeat + toRepeat;
}
return toRepeat;
} else {
return "Not a string";
}
}
}
However I get an Error on the + sign between the 2 toRepeat which states bad operand types for binary operator +. If you know how I could fix this please tell me I would much appreciate it.
You can change
while (i < n){
toRepeat = toRepeat + toRepeat; // operations are not defined for type Object
}
return toRepeat;
to
String tr = (String)toRepeat; // cast to String
while (i < n){
tr = tr + tr; // valid on String
i++; // some condition to terminate
}
return tr;
Edit: As suggested by #oleg, using StringBuilder should be preferred over concatenating Strings in a loop.
Edit2: To increment one character at a time, you can do something like :
String tr = (String)toRepeat; // this would be *
String finalVal = "";
while (i < n){
final = finalVal + tr; // would add * for each iteration
i++;
}
return finalVal;
There are actually three errors here:
The first is the type Object of toRepeat (and it being final, i.e. you may not assign a new value): there is no + for Object. You can cast it to String as shown in the answer before.
Second: your loop does not terminate, because i stays 0.
Third: If you increment i (e.g. i += 1 in the loop). You will get ** after the first loop, **** after the second and 8 stars after the third loop.
I think that Apache lib could help in most cases. It contains StringUtils class with lots of useful method to work with String. This is one of them:
public class RepeatIt {
public static String repeatString(final Object toRepeat, final int n) {
return toRepeat instanceof String ? org.apache.commons.lang3.StringUtils.repeat((String)toRepeat, n) : "Not a string";
}
}

Rewriting the whole String Class methods

My professor have given me a challenging homework, where the idea is to rewrite all the methods in the String classes without using String, StringBuilder, and Wrapper classes. This is for Intro to Java class. I already have some methods done but having a hard time with some other ones. This is for the main class only with no creation of any string inside.
What I have: a "data" as a char[] data for my "MyOwnString" object.
CompareTo method:
public int compareTo(MyOwnString rhs){
if (this.data == rhs.data){
return 0;
} else if (this.data > rhs.data){
return 1;
}
else {
return -1;
}
}
This one shows an error. My guess is that the rhs needs to be declare before being able to compare to any string being assigned to a MyOwnString object.
Since there is a compareTo method and a compareToIgnoreCase, then I would have to add a line to ignore the comparsion?
Update:
This is the code I went with for the compareTo method by creating own method using length of the array.
public int compareTo(MyOwnString cts){
int word1 = data.length;
int word2 = cts.length();
int result = 0;
for (int i=0; i<word1; i++){
for (int j=0;j<word2; j++){
if(word1 == word2){
result = 0;
}
else if (word1 > word2){
result = 1;
}
else {
result = -1;
}
}
}
return result;
}
Since you are not allowed to use String.compareTo()
and since java doesn't support > for your custom objects or char[] for that matter (e.g doesn't support operator overloading) you have to do it programmatically.
In other words you have the two char arrays and you have to loop through all the characters. You compare the first two characters from each of the char arrays (there you can use > or <) if they are == you compare the second two characters and so on.. till you find two characters that break the tie - you can then break your for loop and return the result as -1, 1. If they are tied on every character you return 0.
If you want to implement equals you could just call compareTo and optimize it a bit by checking the lengths of the strings. If they are different then of course the strings are not equal
Update: I am not sure if you ran your code above - try to compile your code and run it before you move forward. I believe it won't even compile.
Here is, I believe, a correct unchecked version. I could have mixed the -1 and 1s as always..
public int compareTo(MyOwnString cts){
int word1Length = ((MyOwnString)this).data.length;
int word2Length = cts.data.length;
for (int i=0; i < Math.min(word1Length,word2Length); i++){
if(this.data[i] == cts.data[i]){
continue;
}
else if (this.data[i] > cts.cts[i]){
return -1;
}
else if (this.data[i] < cts.cts[i]) {
return 1;
}
}
if (word1Length == word2Length){
return 0;
}
else if(word1Length < word2Length){
return 1;
}
else {
return -1;
}
}
public boolean equals(MyOwnString cts){
int word1Length = ((MyOwnString)this).data.length;
int word2Length = cts.data.length;
if (word1Length != word2Length){
return false;
}
else { // if they are equal
int comparison = this.compareTo(cts);
if (comparison==0){
return true;
}
else {
return false;
}
}
}
You can't compare char[] objects with the > operator, since it's not defined on them. You'll have to iterate over the char[] arrays and compare the characters yourself.
BTW, it's very easy to cheat in this assignment, since the code of the String class is available online.

Searching for a string within an array

Below I am trying to create a method which searches through an array for a certain string and returns the position of it, if not there then -1 should be the number returned. Below I search for a word using the method and it returns -1 even though the word is within the array. Why is this?
String answer = "";
System.out.println("Enter word to search within array");
answer = in.next();
public static int search(String[] theWords, String answer) {
int a = -1;
for(int i = 0; i < theWords.length; i++) {
if (answer.equals(theWords[i])){
a = i;
break;
}
}
return a;
}
I can't see anything wrong with the code, but I would recommend eliminating the local variable that holds the return value:
public static int Search(String[] thewords, String answer) {
for (int i = 0; i < thewords.length; i++) {
if (answer.equals(thewords[i])){
return i;
}
}
return -1;
}
With this simplified logic, there's little or no chance of there being a bug in this code.
I assume this is course work, and you are not allowed to use library methods. If you were allowed, your method could be a single line:
return Arrays.asList(theWords).indexOf(answer);
You can optionally make a copy of the array since sorting might be unwanted for consumers of the method
public static int Search(String[] thewords, String answer) {
if(thewords == null) {
throw new NullPointerException();
}
String[] copy = new String[thewords.length];
System.arraycopy(thewords,0,copy,0,copy.length);
Arrays.sort(thewords);
return Arrays.binarySearch(thewords, answer);
}
Note: It returns -pos and not -1
If you need -1:
public static int Search(String[] thewords, String answer) {
if(thewords == null) {
throw new NullPointerException();
}
String[] copy = new String[thewords.length];
System.arraycopy(thewords,0,copy,0,copy.length);
Arrays.sort(thewords);
int idx = Arrays.binarySearch(thewords, answer);
return idx < 0? -1:idx;
}
Concerning your code: I believe the problem would be related to casing or spacing:
Replace with something like: if (answer.equalsIgnoreCase(theWords[i].trim())){
For large arrays go with binary search.

java creating a class method that searches an array for word length

so i've already made a class method that searches for a specific word, but (like most times i find myself on here!) i've had a brain malfunction and can't figure out how to modify it to do what i need. here's what i've got so far:
private static int findFourLetterWord(String[] strings, String key) {
for (int i = 0; i < strings.length; i++)
if (strings[i].equals(key))
return i;
return -1;
}
so this searches an array for 'key' and returns with it's position if it is found. what i'm trying to get it to do is search an array of strings for the first 4 letter word it encounters and return with that word. i would change the first return to be System.out.println(strings[i]); i believe, but i'm not sure how to make it search for the first 4 letter word it finds. tried using a bunch of convoluted substrings but that didn't work. any advice or guidance would be great. thank you in advance.
Your current method is close; you just need to change the condition in the for-loop to check for a length of 4 using String#length() rather than equality to a key argument.
private static String findFourLetterWord(String[] strings) {
for (String str : strings) {
if (str.length() == 4) {
return str;
}
}
return null;
}
Never forget to consult the JavaDocs when you find yourself unsure of what methods are available for your convenience.
Am I understanding your question right?
private static String findFourLetterWord(String[] strings) {
for (int i = 0; i < strings.length; i++)
if (strings[i].length()==4)
return strings[i];
return null;
}
Use substring function to get the first 4 character of the key and string as below:
private static int FindFourLetterWord(String[] strings, String key) {
//Assuming key length is 4 or more
String keyWithFourChars = key.substring(0,4);
for (int i = 0; i < strings.length; i++){
if(strings[i].length() > 3){
if (strings[i].substring(0,4).eqauls(keyWithFourChars)){
return i;
}
}
}
return -1;
}
If you want to just look for 4 chars string, then simply check the length as below:
In this case, you don't need to pass key as parameter.
private static int FindFourLetterWord(String[] strings) {
for (int i = 0; i < strings.length; i++){
if(strings[i].length() == 4){
return i;
}
}
return -1;
}

Categories