0

I have a problem with this little program in Java for which checks if 2 strings are anagrams or not.

I get a StringIndexOutOfBoundsException:

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 6
    at java.lang.String.charAt(Unknown Source)
    at AreAnagrams.areAnagrams(AreAnagrams.java:9)
    at AreAnagrams.main(AreAnagrams.java:30)

This is my code:

public class AreAnagrams {
    public static boolean areAnagrams(String a, String b) {
        int j = 0;
        int i = 0;
        if (a.length() == b.length()) {
            while (i < a.length()) {
                if (a.charAt(i) == b.charAt(j)) {
                    j++;
                    i = 0;
                } else {
                    i++;
                    if (j > a.length()) {
                        return false;
                    }
                }
            }
        } else {
            return false;
        }
        return false;
    }

    public static void main(String[] args) {
        System.out.println(areAnagrams("momdad", "dadmom"));
    }
}
Tom
  • 16,842
  • 17
  • 45
  • 54
v3ctor
  • 105
  • 1
  • 2
  • 10

2 Answers2

2

java.lang.StringIndexOutOfBoundsException happens when you refer to a character index which exceeds the string length.

For example the string "dadmom" - when you call charAt(6), then it will throw this exception, because the character indices are in range from 0 to 5.

You can use the following code to identify anagrams:

public static boolean areAnagrams(String a, String b) {
     char[] aChars = a.replaceAll("\\s", "").toCharArray();
     char[] bChars = b.replaceAll("\\s", "").toCharArray();
     Arrays.sort(aChars);
     Arrays.sort(bChars);
     System.out.println(aChars);
     System.out.println(bChars);

     return Arrays.equals(aChars, bChars);
}

public static void main(String[] args) {
     System.out.println(areAnagrams("momdad", "dadmom"));
}
Tom
  • 16,842
  • 17
  • 45
  • 54
Eranda
  • 1,439
  • 1
  • 17
  • 30
  • how i can solve ? i try with a.charAt(i-1) but i have same result – v3ctor Jun 13 '15 at 15:07
  • @v3ctor Please check Erandas update on his/her answer. Also mind, if you like to use a case-insensitive check (e.g. *MomDad* is an anagram of *dadmom*), then call `toLowerCase` additionally on `a` and `b`. – Tom Jun 13 '15 at 17:20
  • the sort have high cost for computation, is easy solution but i think not the best – v3ctor Jun 14 '15 at 09:43
1

I feel that you have a programming logic error here. For anagrams the criteria should be that the starting from left to right for 1st string the characters should be equal for the 2nd string starting right to left.

I did not find any such thing in your code. I feel you should try the following inside your if block if ( a.length() == b.length()):

int length = a.length();
for(int i = 0; i < length; i++){
    if(a.charAt(i) != b.charAt(length-i-1)){
        return false;
    }
}
return true;

You should also remove the declaration of i and j variables in your code.

Correction

I really got confused with anagram and palindrome. The above answer is correct for palindrome. I am adding to my answer to work for anagram.

I would suggest that you check the strings recursively by changing the method areAnagrams as illustrated below:

public static boolean areAnagrams(String a, String b) {

//If the length of strings is unequal then return false.
    if(a.length() != b.length()){
        return false;
    } 

//Else if the length of strings equals 1 return the equality of the two strings
    if(a.length() == 1){
        return a.equals(b);
    }

//Else replace the first occurrence of the first character 
//of variable `a` with blank string in string variable b. 
//Here if the character is not present in string b then the
//variable b remains unchanged and the length of b would be 
//greater than that of variable `a` in the next recursion.
    b = b.replaceFirst(a.substring(0, 1), "");

//remove the first character in string `a`
    a = a.substring(1, a.length());

//make the recursive call
    return areAnagrams(a, b);
} 
Blip
  • 3,061
  • 5
  • 22
  • 50
  • yes is ok for the example, but if i have "jack" and "ckja" is false – v3ctor Jun 13 '15 at 15:24
  • @v3ctor the anagram of `jack` is `kcaj` and not `ckja` and so it will return `false`. So what you have stated in your comment is actually a correct output. – Blip Jun 13 '15 at 15:46
  • 1
    An anagram is a type of word play, the result of rearranging the letters of a word or phrase to produce a new word or phrase, using all the original letters exactly once , then i can do combination with all 4 char fo string "jack" – v3ctor Jun 13 '15 at 15:50
  • @Blip What you mean is a [palindrome](https://en.wikipedia.org/wiki/Palindrome). – Tom Jun 13 '15 at 17:10
  • @v3ctor Thanks for correcting me. I have corrected my answer now – Blip Jun 14 '15 at 05:22