Last active
June 29, 2017 22:34
-
-
Save matey-jack/403f551be3feda568893fc6a76dca45b to your computer and use it in GitHub Desktop.
Nice Anagram Detector Example in Java 8, with examples in JUnit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.HashMap; | |
import java.util.Map; | |
public class AnagramDetector { | |
public Map<Character, Integer> countLetters(String s) { | |
Map<Character, Integer> result = new HashMap<>(); | |
for (char c : s.toLowerCase().toCharArray()) { | |
result.put(c, result.getOrDefault(c, 0) + 1); | |
// alternative, not reading as nicely, but using one less Map lookup: | |
// result.compute(c, (ignored, oldCount) -> oldCount == null ? 1 : oldCount+1); | |
} | |
return result; | |
} | |
public boolean isAnagramOf(String a, String b) { | |
if (a == null || b == null) { | |
throw new IllegalArgumentException("isAnagramOf: arguments must be non-null."); | |
} | |
if (a.equals(b)) { | |
return true; | |
} | |
return countLetters(a).equals(countLetters(b)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.Arrays; | |
public class AnagramDetectorViaSort { | |
// I wish the library function would already do it like this, but it was made before Java embraced functional programming! | |
public char[] sort(char[] chars) { | |
Arrays.sort(chars); | |
return chars; | |
} | |
public char[] sortedLowerCaseCharsOf(String s) { | |
return sort(s.toLowerCase().toCharArray()); | |
} | |
public boolean isAnagramOf(String a, String b) { | |
if (a == null || b == null) { | |
throw new IllegalArgumentException("isAnagramOf: arguments must be non-null."); | |
} | |
if (a.equals(b)) { | |
return true; | |
} | |
return Arrays.equals(sortedLowerCaseCharsOf(a), sortedLowerCaseCharsOf(b)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.junit.Test; | |
import static org.junit.Assert.assertFalse; | |
import static org.junit.Assert.assertTrue; | |
public class AnagramTest { | |
AnagramDetector underTest = new AnagramDetector(); | |
@Test | |
public void testWithIdentity() { | |
assertTrue(underTest.isAnagramOf("post", "post")); | |
} | |
@Test | |
public void testWithSimpleAnagram() { | |
assertTrue(underTest.isAnagramOf("post", "stop")); | |
} | |
@Test | |
public void testWithAnagram_DuplicateLetter() { | |
assertTrue(underTest.isAnagramOf("Kammer", "Kramem")); | |
} | |
@Test | |
public void testWithNoAnagram_Simple() { | |
assertFalse(underTest.isAnagramOf("post", "plus")); | |
} | |
@Test | |
public void testWithNoAnagram_DuplicateLetters() { | |
assertFalse(underTest.isAnagramOf("post", "stopp")); | |
} | |
@Test | |
public void testWithNoAnagram_SeveralDuplicateLetters() { | |
assertFalse(underTest.isAnagramOf("flussschifffahrt", "iffussahrtsch")); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I did this as a coding exercise and implemented my first solution idea with the Map, because it was good enough and I wanted to get it done.
Later search revealed a solution using less code (sorting the char arrays and comparing them) as well as a solution that is a bit faster (using int arrays indexed by the character code as counters instead of the Map). Obviously the faster solution requires a known and fixed set of characters (such as the English alphabet which is very boring and restricted). Using just the 26 Latin characters would already fail for my native language and just as well for a lot of other languages, which makes me think that my solution is not so bad after all.
Although the sorting idea is really nice, so I also added it for comparison.