2

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;
        }

    }
}
1
  • Remove the spaces before converting to array: char[] Ca = a.replaceAll("\\s", "").toCharArray(); Commented Nov 23, 2021 at 20:54

4 Answers 4

2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

I think no need to create a new String when we can do it without it.
@oleg.cherednik In his code indeed S1 and S2 are used for compareTo, and I find String usage not bad: Unicode letters, Cyrillic letters, Locale toUpperCase (German ß becomes SS, Turkish i-with/without-dot). I just upvoted your answer, though a Map<Integer, Integer> and using code points would be nicer (in an ideal world). I went with OP's code.
2
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;
}

Comments

2

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));
}

Comments

1

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);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.