A solution, optimized for performance.
What does differently to other solutions:
- Only in the absolute worst case it iterates once through text1 and once through text2
- Fails fast: returns false as soon as it encounters a character in text1 that is not part of text2
- Stores histogram as
int[]
, which is much faster than HashMaps or similar
- Can process strings with any character (even emojis 😉)
Example Code:
public static boolean check(String text1, String text2) {
requireNonNull(text1, "text1 must not be null");
requireNonNull(text2, "text2 must not be null");
if (text1 == text2) return true;
var text1Chars = text1.toCharArray();
var text2Chars = text2.toCharArray();
if (text1Chars.length != text2Chars.length) return false;
var text2Counts = new int[Character.MAX_CODE_POINT];
var text2Index = 0;
loopThroughText1:
for (char charOfText1 : text1Chars) {
if (text2Counts[charOfText1] > 0) {
text2Counts[charOfText1]--;
} else {
while (text2Index < text2Chars.length) {
var charOfText2 = text2Chars[text2Index++];
if (charOfText1 == charOfText2) {
continue loopThroughText1;
}
text2Counts[charOfText2]++;
}
return false;
}
}
return text2Index >= text2Chars.length;
}
The corresponding test method:
@ParameterizedTest
@CsvSource({
"a,a,true",
"a,b,false",
"aa,a,false",
"a,aa,false",
"aa,aa,true",
"vhjsd682ahjsvdi7861rUZVFD/Ias6srf871r23,vhjsd682ahjsvdi7861rUZVFD/Ias6srf871r23,true",
"A,a,false",
"🎈,🎈,true",
"🎈,💣,false",
})
public void check(String text1, String text2, boolean expected) {
assertEquals(AnagramChecker.check(text1, text2), expected);
}
Anagram
in your case? – ArchednewStr
withs2
(less a letter) every time you get a match. For example, ifs2
isab
, when you matchb
,newStr
becomesa
, then when you matcha
,newStr
does not become the empty string, but becomesb
(since it iss2
less the matching character). It is not the only bug in your code (repeated characters, different length strings), but it is the one that you are going to see first. – NonscheduledArrays.equals( a.chars().filter(Character::isAlphabetic).sorted().toArray(), b.chars().filter(Character::isAlphabetic).sorted().toArray());
– Hopper