compare two strings in java - java

I am trying to compare to strings by using an algorithm as you see below
My code does not work .. eclipse does not show any error before I run the code
public class MysteryClass {
public static void mystery(String n) {
String k= "alla";
if (k.charAt(k.length())==n.charAt(n.length())) {
System.out.println("palindrom");
} else {
System.out.println("not palindrom");
}
}
public static void main(String[] args) {
MysteryClass.mystery("alla");
}
}
but we I run the code I get
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 4
at java.lang.String.charAt(String.java:658)
at shapes.MysteryClass.mystery(MysteryClass.java:6)
at shapes.MysteryClass.main(MysteryClass.java:15)
How to fix that??
thanks

Not sure what you want, but your StringIndexOutOfBoundsException is cause by access an array's index which is does not exist.
Take your String k = "alla" as example, k.length() will return 4 because "alla" have four characters, and you are accessing k.charAt(4), the "alla"break into as follows:
a l l a // string
0 1 2 3 // index
As you can see the last index of "alla" is 3, that's why you get StringIndexOutOfBoundsException. But you can solve it using .length() -1 as follow:
if (k.charAt(k.length()-1)==n.charAt(n.length()-1)) {
System.out.println("palindrom");
} else {
System.out.println("not palindrom");
Alternative:
If you want to compare two string, you can use .equals method too, as follow:
if (k.equals(n)) {
System.out.println("palindrom");
} else {
System.out.println("not palindrom");

Two issues with your code:-
1)By your logic, tigert is also palindrome but it is actually not.Palindrome is when the word is completely reversed and it is still the same.Currently,you are checking only the first and last character
2)String is internally held as a char array and arrays have indexing from 0 to length -1

The error is caused by the statement if (k.charAt(k.length())==n.charAt(n.length()))
Above k.length() returns 4. the statement then resolves to:
(k.charAt(4)
This will through error because the function charAt counts from the index 0. So it counts the characters at index 0, 1, 2, 3 and you are asking it to fetch character at index 4 which does not exist.
A suggested alternative is :
(k.charAt(k.length() -1)==n.charAt(n.length()-1))

Related

Java String Concatenation Error "String index out of range: -1"

First off I know there are a lot of questions about "String index out of range", I have looked through them but can't find anyone having the same problem as me.
I have to write a simple program:
Given a string, return a "rotated left n" version where the first n chars are moved to the end.
leftN("Hello",2) → "lloHe"
leftN("java",0) → "java"
leftN("Hi,1") → "iH"
So I wrote the following:
package string;
public class LeftN {
public static String leftN(String str, int n) {
if (str.length() > 1 && n > 0) {
String a = str.substring(n);
String b = str.substring(0, n);
return a + b;
} else {
return str;
}
}
}
Question:
When I return just a or just b I get a valid output (if I add the output of a and b on paper I am getting the rotated left n version of the string). However, when I return the concatenation of a + b I get the String index out of range: -1 error, what can it be that is causing this?
Now I know that this error has to do with referencing a value that is out of bounds for the string and understand how this works when creating a substring. What is really confusing me is how adding two seemingly valid strings can give me this error?
Note: I have a test class provided that I am testing it against to see if it's giving the right output but I am not sure if I am allowed to post it online so that is why I am not providing it.
I can reproduce your exception by passing an n greater than the length of str:
leftN("abc", 4);
results in:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.base/java.lang.String.substring(String.java:1850)
at Ideone.leftN(Main.java:12)
at Ideone.main(Main.java:22)
You need to handle the case of n being too large (or, indeed, negative). For example:
Throw an IllegalArgumentException
Use n % str.length() instead.

Removing a substring from a string, repeatedly

Problem:
Remove the substring t from a string s, repeatedly and print the number of steps involved to do the same.
Explanation/Working:
For Example: t = ab, s = aabb. In the first step, we check if t is
contained within s. Here, t is contained in the middle i.e. a(ab)b.
So, we will remove it and the resultant will be ab and increment the
count value by 1. We again check if t is contained within s. Now, t is
equal to s i.e. (ab). So, we remove that from s and increment the
count. So, since t is no more contained in s, we stop and print the
count value, which is 2 in this case.
So, here's what I have tried:
Code 1:
static int maxMoves(String s, String t) {
int count = 0,i;
while(true)
{
if(s.contains(t))
{
i = s.indexOf(t);
s = s.substring(0,i) + s.substring(i + t.length());
}
else break;
++count;
}
return count;
}
I am just able to pass 9/14 test cases on Hackerrank, due to some reason (I am getting "Wrong Answer" for rest of the cases). After a while, I found out that there is something called replace() method in Java. So, I tried using that by replacing the if condition and came up with a second version of code.
Code 2:
static int maxMoves(String s, String t) {
int count = 0,i;
while(true)
{
if(s.contains(t))
s.replace(t,""); //Marked Statement
else break;
++count;
}
return count;
}
But for some reason (I don't know why), the "Marked Statement" in the above code gets executed infinitely (this I noticed when I replaced the "Marked Statement" with System.out.println(s.replace(t,""));). I don't the reason for the same.
Since, I am passing only 9/14 test cases, there must be some logical error that is leading to a "Wrong Answer". How do I overcome that if I use Code 1? And if I use Code 2, how do I avoid infinite execution of the "Marked Statement"? Or is there anyone who would like to suggest me a Code 3?
Thank you in advance :)
Try saving the new (returned) string instead of ignoring it.
s = s.replace(t,"");
replace returns a new string; you seemed to think that it alters the given string in-place.
Try adding some simple parameter checks of the strings. The strings shouldn't be equal to null and they should have a length greater than 0 to allow for counts greater than 0.
static int maxMoves(String s, String t) {
int count = 0,i;
if(s == null || s.length() == 0 || t == null || t.length() == 0)
return 0;
while(true)
{
if(s.contains(t) && !s.equals(""))
s = s.replace(t,""); //Marked Statement
else break;
++count;
}
return count;
}
You might be missing on the edge cases in the code 1.
In code 2, you are not storing the new string formed after the replace function.
The replace function replaces each substring of this string that matches the literal target sequence with the specified literal replacement sequence.
Try this out:
public static int findCount(String s, String t){
if( null == s || "" == s || null == t || "" == t)
return 0;
int count =0;
while(true){
if(s.contains(t)){
count++;
int i = s.indexOf(t);
s = s.substring(0, i)+s.substring(i+t.length(), s.length());
// s = s.replace(t,"");
}
else
break;
}
return count;
}
String r1="ramraviraravivimravi";
String r2="ravi";
int count=0,i;
while(r1.contains(r2))
{
count++;
i=r1.indexOf(r2);
StringBuilder s1=new StringBuilder(r1);
s1.delete(i,i+r2.length());
System.out.println(s1.toString());
r1=s1.toString();
}
System.out.println(count);
First of all no logical difference in both the codes.
All the mentioned answers are to rectify the error of code 2 but none told how to pass all (14/14) cases.
Here I am mentioning a test case where your code will fail.
s = "abcabcabab";
t = "abcab"
Your answer 1
Expected answer 2
According to your code:
In 1st step, removig t from index 0 of s,
s will reduce to "cabab", so the count will be 1 only.
But actual answer should be 2
I first step, remove t from index 3 of s,
s will reduced to "abcab", count = 1.
In 2nd step removing t from index 0,
s will reduced to "", count = 2.
So answer would be 2.
If anyone know how to handle such cases, please let me know.

Custom compare string method throwing indexarrayoutofbounds

I have a custom compare method:
public int compareStrings(String one, String two) {
int compareAmount = 0;
if (one.length() == two.length()) {
compareAmount++;
} else {
compareAmount--;
}
int x = 0;
for (char i : one.toCharArray()) {
if (!(x > two.length())) {
if (two.charAt(x) == i) {
compareAmount++;
}
x++;
}
}
return compareAmount;
}
If string one is "Ok" and String two is "Lets give it a go" it throws java.lang.StringIndexOutOfBoundsException: String index out of range: 2. I cannot see were I've gone wrong!
You are going all the way to two.length() instead of stopping at two.length() - 1. This doesn't work since arrays are indexed from 0..length()-1.
Just change your if condition inside the loop to fix the problem:
if (!(x >= two.length())) {
If the length of the String two is 11, the last index is 10. You're just checking if x is NOT greater than the length of two. But it might be equal which is out of bounds. Just change it to >=
Dude, first of all, don't reimplement this kind of algorithms.
Use the compareTo(String) method defined in the String class.
You can also learn from the JDKs source code and see how they implement this method http://hg.openjdk.java.net/jdk7u/jdk7u6/jdk/file/8c2c5d63a17e/src/share/classes/java/lang/String.java#l1096
If you need a custom comparator for a specific class, you must implement the Comparator interface.
If you are starting to learn java and want to get good at it. At least make a full read of the official Java tutorial by oracle

delete array [] elements

I am working on some data structures - after searching for an element, I am attempting to delete that element - but throws
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at SearchArray.deleteElements(SearchArray.java:68)
at SearchArrayDemo.main(SearchArrayDemo.java:25)
this is my method
void deleteElements(int value)
{
int j,k;
for (j=0;j<setArray.length;j++)
if ( value == setArray[j])
break;
if
(setArray[j] == setArray.length)
System.out.print("no item found");
else
{
for( k=j;k<setArray.length;k++)
`setArray[k]=setArray[k+1];`
k=setArray.length-1;
setArray[j]=0;
System.out.println("item deleted");
}`
and main method used to call that functions deleteElements
sa.deleteElements(5);
I did not include all the code for conciseness, this is the line where code breaks
setArray[k]=setArray[k+1];
please let me know if remaining code is required. thanks all for your help.
The problem here is that your loop end condition is
k<setArray.length
, but then you use
setArray[k+1]
Change the condition to
k < setArray.length - 1
for( k=j;k<setArray.length;k++)
setArray[k]=setArray[k+1]; \\ K+1 (invalid index when k = setArray.length-1
In your code, this will fail for the last element. Hence you get the exception
In an Array last index will be Array.length-1. In your case for the last element the code fails because k=Array.length-1 (last index) and k+1 = Array.length (which does not exist). Hence it throws out of bounds exception.
Your first for loop has some dead-code:
if(setArray[j] == setArray.length)
System.out.print("no item found");
This condition will never be reached in your loop for (j=0;j<setArray.length;j++)
if u want to delete the element in array 4
class arrayserch{
public int value(){
int[] arr={1,2,3,4,5,6;
int i=0;
for(int a:arr){
if(a==4){
return i;
}
else
i++;
}
return=-1;
}
}
class example{
public static void main(string arags[]){
arrsearch as=new arrrsearch();
int i=as.value();
if(i!=-1){
arr.length--;
for(int j=i;j<arr.length;j++)
{
arr[j]=arr[i++];
}
}
}
this may solve ur problem
Problem is this snippet:
for( k=j;k<setArray.length;k++)
setArray[k]=setArray[k+1];
When k == setArray.length - 1, setArray[k+1] goes beyond setArray boundaries
i dont't know your code
but line
setArray[k]=setArray[k+1];
it's out boundaries array

Java string split function acting strange

I am noticing strange behaviour when using the split() method in Java.
I have a string as follows: 0|1|2|3|4|5|6|7|8|9|10
String currentString[] = br.readLine().split("\\|");
System.out.println("Length:"+currentString.length);
for(int i=0;i < currentString.length;i++){
System.out.println(currentString[i]);
}
This will produce the desired results:
Length: 11
0
1
2
3
4
5
6
7
8
9
10
However if I receive the string: 0|1|2|3|4|5|6|7|8||
I get the following results:
Length: 8
0
1
2
3
4
5
6
7
8
The final 2 empties are omitted. I need the empties to be kept. Not sure what i am doing wrong. I have also tried using the split in this manner as well. ...split("\\|",-1);
but that returns the entire string with a length of 1.
Any help would be greatly appreciated!
The default behavior of split is to not return empty tokens (because of a zero limit). Use the two parameter split method with a limit of -1 will give you all empty tokens in the return.
UPDATE:
Test code as follows:
public class Test {
public static void main(String[] args) {
String currentString[] = "0|1|2|3|4|5|6|7|8||".split("\\|", -1);
System.out.println("Length:"+currentString.length);
for(int i=0;i < currentString.length;i++){ System.out.println(currentString[i]); }
}
}
Output as follows:
Length:11
0
1
2
3
4
5
6
7
8
--- BLANK LINE --
--- BLANK LINE --
The "--- BLANK LINE --" is put in by me to show that the return is blank. It is blank once for the empty token after 8| and once for the empty trailing token after the last |.
Hope this clears things up.
String.split() is weird.
Its extreme weirdness, in this and other ways, are some of the reasons why we made Splitter.
It has less surprising behavior and lots of flexibility.
My Java is a little bit rusty, but shouldn't it be:
String currentString[] = "0|1|2|3|4|5|6|7|8||".split("\\|");
System.out.println("Length:"+currentString.length);
for(int i = 0; i < currentString.length; i++)
{
System.out.println(currentString[i]);
}
IMO, I think this is the default behavior of split, Anyway please try this:
String currentString[] = br.readLine().replace("||","| |").split("\|");
System.out.println("Length:"+currentString.length);
for(int i=0;i < currentString.length;i++){
System.out.println(currentString[i]);
}
This has not been tested yet, but i think this should do the trick.
You need to use indexOf() and then substring() for this to work. I don't think you can empty string by using split() only.
Please check the following code, I used your solution, it works:
public class SplitTest
{
public static void main(String[] args)
{
String text = "0|1|2|3|4|5|6|7|8||";
String pattern = "\\|";
String [] array = text.split(pattern, -1);
System.out.println("array length:" + array.length);
for(int i=0; i&lt array.length; i++)
System.out.print(array[i]+ " ");
}
}
output is:
array length:11
0 1 2 3 4 5 6 7 8

Categories

Resources