Java equals causes ArrayIndexOutOfBoundsException - java

I want to compare two Strings in two different arrays. Strings are stored in s1 and s2 variables. This part works great, but if I add if condition, if(s1.equals(s2)){/*...*/}, I get ArrayIndexOutOfBoundsException.
Look at these two screen shots:
In both cases arrays have same values. The only thing that was changed is the if condition.
Image#1
Image#2
Code:
Vagon tmp = first;
int stevec = 1;
while(tmp != null){
double trenutenVolumen = 0;
for(int j = 0; j < tmp.opisTovora.length; j++){
trenutenVolumen += tmp.volumenTovora[j];
}
double lahkoDodamVolumna = tmp.volumen-trenutenVolumen;
double lahkoDodamTeze = lokomotiva.najvecjaMasa-trenutnaTeza;
System.out.println("len: "+tmp.opisTovora.length);
if(tmp.tipTovora == tipTovora[0] && lahkoDodamVolumna >= volumenTovora[0] && trenutnaTeza+tezaTovora <= lokomotiva.najvecjaMasa){
if(!tmp.tipTovora){
String s1 = tmp.opisTovora[0];
String s2 = opisTovora[0];
//if(s1.equals(s2)){
System.out.println(s1 + " == " + s2);
System.out.println("LAHKO DODAM TOVOR #" + (i+1) + " => V VAGON #" + stevec);
break;
//}
}
if(tmp.tipTovora){
System.out.println("LAHKO DODAM TOVOR #" + (i+1) + " => V VAGON #" + stevec);
break;
}
}
stevec++;
tmp = tmp.next;
}

Your exception is on this line - String s1 = tmp.opisTovora[0]. It means that tmp.opisTovora is an empty array, so tmp.opisTovora[0] is out of the bounds of that array.
It has nothing to do with equals.

Related

String keeps initializing as null

My string keeps initializing itself as null... or at least it seems that way. I am trying to make a custom toString function for my matrix. this.matrixArray is a 2D array of dimensions 'm x n'.
public String toString() {
String stringAsMatrix = "";
String dimensions = this.m + "," + this.n + "\n";
stringAsMatrix += dimensions;
String[] dataRows = new String[this.m];
for (int row = 0; row < this.m; row++) {
for (int column = 0; column < this.n; column++) {
String elementString = "";
elementString += this.matrixArray[row][column];
if (column == this.n-1) {
dataRows[row] += elementString + "\n";
} else {
dataRows[row] += elementString + ","; // Only add a comma if this isn't the last element in the row
}
}
stringAsMatrix += dataRows[row];
}
return stringAsMatrix;
}
This is the output I get but I don't understand why it prints 'null' before my string. The dimensions are correct (the matrix array is indeed 2x2). The values themselves are also correct (my matrix is {{1,2}, {3,4}})
2,2
null1.0,2.0
null3.0,4.0
dataRows[row] += elementString + "\n";
dataRows[row] is starting out with null in it. So it becomes
dataRows[row] = null + elementString + "\n"
...which is exactly what you get. Instead, write
dataRows[row] = elementString + "\n";

indexOf(String) linked list char logic error

First year CS student. Ive tried to implement an indexOf(String) method in my custom MyStringbuilder class (in this case with a linked list of char). I cant get the right output for finding the query string at the front or not finding it but anything in the middle of of the initial string doesnt work. Specific example below in my test driver.
public int indexOf(String str)
{
int index =-1; //index at which str is first found in linked list string of chars
int count = 0; //num of matches
int firstI = -1;
int sI=0; // dynamic counter variable to allow str.length and for loop to interact
CNode currNode = firstC;
for (int i = 0; i < length; i++)
{
if (currNode.data == str.charAt(sI))
{
if (count < 1)
firstI = i;
count++;
}
if (count == 0 && (sI == str.length()-1))
sI=0;
if (count == str.length())
{
index = firstI;
break;
}
if (count > 0 && currNode.data != str.charAt(sI))
{
sI = 0;
count = 0;
}
currNode = currNode.next; //increment
sI++;
}
return index;
}
TEST DRIVER CLASS
System.out.println("\nTesting indexOf method");
b1 = new MyStringBuilder("who is whoing over in whoville");
String s1 = new String("who");
String s2 = new String("whoing");
String s3 = new String("whoville");
String s4 = new String("whoviller");
String s5 = new String("wacky");
int i1 = b1.indexOf(s1);
int i2 = b1.indexOf(s2);
int i3 = b1.indexOf(s3);
int i4 = b1.indexOf(s4);
int i5 = b1.indexOf(s5);
System.out.println(s1 + " was found at " + i1);
System.out.println(s2 + " was found at " + i2);
System.out.println(s3 + " was found at " + i3);
System.out.println(s4 + " was found at " + i4);
System.out.println(s5 + " was found at " + i5);
You don't set firstI anywhere inside the loop, but it ends up the value you return. This will always return -1.
Additionally, I think you might want to take another look at the variable sI, it doesn't seem to serve any real purpose. If count is ever != sI then you have an issue, so you could just get rid of sI completely.

Parsing and replacing doubles in Java String

I am writing java code for translating signals. If a given string (INPUT) is:
C*12.387a0d14assc7*18.65d142a
Its translation (OUTPUT) should be:
C*12387:1000a0d14assc7*1865:100d142a
ALGORITHM:
Wherever in the string a star(*) follows a number containing decimal (in this string there are two, first is '*12.387' and the second is *18.65'), this number is to be changed into fraction as in the above example 12.387 is converted into 12387:1000 and 18.65 converted into 1865:100
If decimal number is isolated I can convert it into fraction with the following code:
double d = 12.387;
String str = Double.toString(d);
String[] fraction = str.split("\\.");
int denominator = (int)Math.pow(10, fraction[1].length());
int numerator = Integer.parseInt(fraction[0] + "" + fraction[1]);
System.out.println(numerator + ":" + denominator);
But I do not how to separate the substring of decimal number from the string it contains. Being new to java and programming I need help. Thanks in anticipation.
Using regex and capturing groups is a good way to implement your parsing:
String s = "C*12.387a0d14assc7*18.65d142a";
StringBuffer result = new StringBuffer();
Matcher m = Pattern.compile("\\*(\\d+)\\.(\\d+)").matcher(s);
while (m.find()) {
String num = m.group(1);
String denom = m.group(2);
String divisor = "1" + new String(new char[denom.length()]).replace("\0", "0");
String replacement = "*" + num + denom + ":" + divisor;
m.appendReplacement(result, replacement);
}
m.appendTail(result);
System.out.println(result.toString());
I was writing a solution which uses regex'es but then tried without them. The solution here is general (for any programming language). Sure it would be interesting to see if it is faster than regex based solution. Anyway I suspect that regex based solution might be faster. Please see this solution too (it is not perfect though :) ).
import java.util.*;
class DoubleConvert
{
public static void main (String[] args)
{
StringBuilder buffer = new StringBuilder("C*12.387a0d14assc7*18.65d142a");
int j, m, k;
int i = 0;
while (i < buffer.length())
{
if (buffer.charAt(i) == '*')
{
m = -1; k = -1;
j = i; //remember where * found
while ( i + 1 < buffer.length() )
{
i++;
if (Character.isDigit(buffer.charAt(i)))
{
continue;
}
else if (buffer.charAt(i) == '.')
{
m = i; // remember where . found
while (i + 1 < buffer.length())
{
i++;
if (Character.isDigit(buffer.charAt(i)))
{
continue;
}
else
{
k = i; //remember the last position
break;
}
}
}
else //let's see what we got
{
if (m > 0 && j > 0 && m - j > 0 && k - m > 0) //there must exist strings
{
System.out.println("Found " + buffer.substring(j, m)
+ " second part " + buffer.substring(m, k));
buffer.replace(j+1, k,
buffer.substring(j+1, m) +
buffer.substring(m+1, k) +
":1" +
new String(new char[k-1-m]).replace("\0","0"));
}
break;
}
}
}
else
{
i++;
}
}
System.out.println("Result " + buffer);
}
}
The output
Found *12 second part .387
Found *18 second part .65
Result C*12387:1000a0d14assc7*1865:100d142a

Merging and Sorting String Arrays

I am trying to finish my assignment, but I am not sure how to complete it.
I have 3 arrays in my code, each of which have first names and last names (the last name comes before the first one in the arrays).
Which function should I use in order to decided whether a string is before the other?
I was thinking compare, but I'm not too sure how to implement it.
This is my code so far:
public static void main(String[] args)
{
String[] section1 = {"Curie, Marie", "Feynman, Richard", "Germain, Sophie",
"Turing, Alan"};
String[] section2 = {"Bolt, Usain", "Graf, Steffi","Hamm, Mia"};
String[] section3 = {"Bach, Johann Sebastian", "Beethoven, Ludwig van",
"Mozart, Wolfgang Amadeus", "Schumann, Clara"};
String[] merged = mergeSortedArrays(section1, section2);
String[] merged = mergeSortedArrays(merged, section3);
for(int i = 0; i < merged.length(); i ++)
System.out.print(merged[i]);
}
//Do not change the method header
public static String[] mergeSortedArrays(String[] a1, String[] a2)
{
int i = 0, j = 0, k = 0;
while(a1[i] != null && a2[j] != null)
{
if(a1[i] "comes before" a2[j])
{
merged[k] = a1[i];
i++;
else {
merged[k] = a2[j];
j++;
}
k++;
}
return merged;
}
}
To compare two strings, use
if(a1[i].compareTo(a2[j]) <= 0) { //Means: a1[i] <= a2[j]
System.out.println("a1[" + i + "] (" + a1[i] + ") is less-than-or-equal-to a2[" + i + "] (" + a2[i] + "));
}
Or
if(a1[i].compareTo(a2[j]) < 0) { //Means: a1[i] < a2[j]
System.out.println("a1[" + i + "] (" + a1[i] + ") is less than a2[" + i + "] (" + a2[i] + "));
}
I recommend the comments as I've done, because I find looking at the compareTo function very confusing. I have to keep reminding myself that the operator is sort of "in place" of the compareTo. I always comment it like this.
I've noticed some serious issues with your code, unrelated to string comparison:
Your else has no close curly-brace before it.
The object merged is never declared in the mergeSortedArrays function
Your while loop needs to check that the array indexes are not too high given the arrays, or you're going to get an ArrayIndexOutOfBoundsException
anArray.length() is incorrect. Eliminate the parentheses.

Checking if a string matches all characters but one of another string

I have a list of strings and with each string I want to check it's characters against every other string to see if all it's characters are identical except for one.
For instance a check that would return true would be checking
rock against lock
clock and flock have one character that is different, no more no less.
rock against dent will obviously return false.
I have been thinking about first looping through the list and then having a secondary loop within that one to check the first string against the second.
And then using split(""); to create two arrays containing the characters of each string and then checking the array elements against each other (i.e. comparing each string with the same position in the other array 1-1 2-2 etc...) and so long as only one character comparison fails then the check for those two strings is true.
Anyway I have a lot of strings (4029) and considering what I am thinking of implementing at the moment would contain 3 loops each within the other that would result in a cubic loop(?) which would take a long long time with that many elements wouldn't it?
Is there an easier way to do this? Or will this method actually work okay? Or -hopefully not- but is there some sort of potential logical flaw in the solution I have proposed?
Thanks a lot!
Why not do it the naive way?
bool matchesAlmost(String str1, String str2) {
if (str1.length != str2.length)
return false;
int same = 0;
for (int i = 0; i < str1.length; ++i) {
if (str1.charAt(i) == str2.charAt(i))
same++;
}
return same == str1.length - 1;
}
Now you can just use a quadratic algorithm to check every string against every other.
Assuming the length of two strings are equal
String str1 = "rock";
String str2 = "lick";
if( str1.length() != str2.length() )
System.out.println( "failed");
else{
if( str2.contains( str1.substring( 0, str1.length()-1)) || str2.contains( str1.substring(1, str1.length() )) ){
System.out.println( "Success ");
}
else{
System.out.println( "Failed");
}
}
Not sure if this is the best approach but this one works even when two strings are not of same length. For example : cat & cattp They differ by one character p and t is repeated. Looks like O(n) time solution using additional space for hashmap & character arrays.
/**
* Returns true if two strings differ by one character
* #param s1 input string1
* #param s2 input string2
* #return true if strings differ by one character
*/
boolean checkIfTwoStringDifferByOne(String s1, String s2) {
char[] c1, c2;
if(s1.length() < s2.length()){
c1 = s1.toCharArray();
c2 = s2.toCharArray();
}else{
c1 = s2.toCharArray();
c2 = s1.toCharArray();
}
HashSet<Character> hs = new HashSet<Character>();
for (int i = 0; i < c1.length; i++) {
hs.add(c1[i]);
}
int count = 0;
for (int j = 0; j < c2.length; j++) {
if (! hs.contains(c2[j])) {
count = count +1;
}
}
if(count == 1)
return true;
return false;
}
Assuming that all the strings have the same length, I think this would help:
public boolean differByOne(String source, String destination)
{
int difference = 0;
for(int i=0;i<source.length();i++)
{
if(source.charAt(i)!=destination.charAt(i))
{
difference++;
if(difference>1)
{
return false;
}
}
}
return difference == 1;
}
Best way is to concatenate strings together one forward and other one in reverse order. Then check in single loop for both ends matching chars and also start from middle towards ends matching char. If more than 2 chars mismatch break.
If one mismatch stop and wait for the next one to complete if it reaches the same position then it matches otherwise just return false.
public static void main(String[] args) {
New1 x = new New1();
x.setFunc();
}
static void setFunc() {
Set s = new HashSet < Character > ();
String input = " aecd";
String input2 = "abcd";
String input3 = new StringBuilder(input2).reverse().toString();
String input4 = input.concat(input3);
int length = input4.length();
System.out.println(input4);
int flag = 0;
for (int i = 1, j = length - 1; j > i - 1; i++, j--) {
if (input4.charAt(i) != input4.charAt(j)) {
System.out.println(input4.charAt(i) + " doesnt match with " + input4.charAt(j));
if (input4.charAt(i + 1) != input4.charAt(j)) {
System.out.println(input4.charAt(i + 1) + " doesnt match with " + input4.charAt(j));
flag = 1;
continue;
} else if (input4.charAt(i) != input4.charAt(j - 1)) {
System.out.println(input4.charAt(i) + " doesnt match with " + input4.charAt(j - 1));
flag = 1;
break;
} else if (input4.charAt(i + 1) != input4.charAt(j - 1) && i + 1 <= j - 1) {
System.out.println(input4.charAt(i + 1) + " doesnt match with xxx " + input4.charAt(j - 1));
flag = 1;
break;
}
} else {
continue;
}
}
if (flag == 0) {
System.out.println("Strings differ by one place");
} else {
System.out.println("Strings does not match");
}
}

Categories

Resources