How to ignore spaces while Sorting a string in java?

Viewed 170

I tried to code a program to detect an anagram with 2 Strings given. My approach is to convert both strings to char Arrays and then sort them before comparing them. I know I could use the sort() function but I don't want to use any imports for training purposes.

The problem is i want my programm to ignore blanks while scanning for an anagram. in the current version the ouput is like this: (triangle, relating) ---> true (tri angle, relating) ---> false

while it should be both true.

i would be thankful for any help!

heres my code, (please ignore my comments):

public static boolean anagramCheck(String a, String b) {
        boolean r = true;
        // In Char Arrays umwandeln /
        char[] Ca = a.toCharArray();
        char[] Cb = b.toCharArray();

        // Laengen Abfrage
        int L1 = Ca.length;
        int L2 = Cb.length;

        // Erste For-Schleife

        for (int i = 0; i < L1; i++) {
            for (int j = i + 1; j < L1; j++) {
                if (Ca[j] < Ca[i]) {
                    char temp = Ca[i];
                    Ca[i] = Ca[j];
                    Ca[j] = temp;
                }
            }
        }

        // Zweite For-schleife

        for (int i = 0; i < L2; i++) {
            for (int j = i + 1; j < L2; j++) {
                if (Cb[j] < Cb[i]) {
                    char temp = Cb[i];
                    Cb[i] = Cb[j];
                    Cb[j] = temp;
                }
            }
        }

        // Char Arrays zu Strings
        String S1 = String.valueOf(Ca);
        String S2 = String.valueOf(Cb);

        // Vergleich und Ausgabe

        if (S1.compareTo(S2) == 0) {
            return r;
        }

        else {
            r = false;
            return r;
        }

    }
}
4 Answers

The String.replace(String, String) is the non-regexp replace method. So remove all spaces:

    String S1 = String.valueOf(Ca).replace(" ", "");
    String S2 = String.valueOf(Cb).replace(" ", "");

It would be nicer to do this on a and b.

public static boolean isAnagram(String one, String two) {
    char[] letters = new char[26];

    for (int i = 0; i < one.length(); i++) {
        char ch = Character.toLowerCase(one.charAt(i));

        if (Character.isLetter(ch))
            letters[ch - 'a']++;
    }

    for (int i = 0; i < two.length(); i++) {
        char ch = Character.toLowerCase(two.charAt(i));

        if (Character.isLetter(ch))
            letters[ch - 'a']--;
    }

    for (int i = 0; i < letters.length; i++)
        if (letters[i] != 0)
            return false;

    return true;
}

Generally, less code is better (if it’s readable). And learning a language means learning the built in libraries.

Here’s a method to return a String of sorted chars:

public static String sortChars(String str) {
    return str.replace(" ", "").chars().sorted()
      .mapToObj(c -> (char)c + "")
      .collect(Collectors.joining(""));
}

With this method, your main method becomes:

public static boolean anagramCheck(String a, String b) {
    return sortedChars(a).equals(sortedChars(b));
}

Refactoring like this, using well-named methods makes your code easier to understand, test, debug and maintain.


It’s worth noting that you don’t actually need a sorted String… a sorted array would serve equally well, and requires less code:

public static int[] sortChars(String str) { return str.replace(" ", "").chars().sorted().toArray(); }

public static boolean anagramCheck(String a, String b) {
    return Arrays.equal(sortedChars(a), sortedChars(b));
}

A frequency map could be created with the characters from String one incrementing and the characters from String two decrementing, then the resulting map should contain only 0 as values.

To skip non-letters, Character::isLetter can be used.

public static boolean isAnagram(String a, String b) {
    Map<Character, Integer> frequencies = new HashMap<>();
    for (int i = 0, na = a.length(), nb = b.length(), n = Math.max(na, nb); i < n; i++) {
        if (i < na && Character.isLetter(a.charAt(i)))
            frequencies.merge(Character.toLowerCase(a.charAt(i)),  1, Integer::sum);

        if (i < nb && Character.isLetter(b.charAt(i)))
            frequencies.merge(Character.toLowerCase(b.charAt(i)), -1, Integer::sum);
    }
    return frequencies.values().stream().allMatch(x -> x == 0);
}
Related