BAEL-3418 Check If Two Strings Are Anagrams in Java (#8139)

* BAEL-3418 Check If Two Strings Are Anagrams in Java

* BAEL-3418 Update code based on code review feedback.

* BAEL-3418 Update comments and rename constant based on code review feedback.

* Move the repository to core-java-modules/core-java-string-algorithms-3/

* BAEL-3418 Only support alpha characters for the anagram

* BAEL-3418 use preprocess in a separate method

* BAEL-3418 Remove the temp variables
This commit is contained in:
wugangca
2019-12-07 13:35:19 -07:00
committed by ashleyfrieze
parent 916260ff89
commit ef0128e21a
4 changed files with 208 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
package com.baeldung.anagram;
import java.util.Arrays;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.Multiset;
public class Anagram {
// This definition only works for single byte encoding character set.
// For multibyte encoding, such as UTF-8, 16, 32 etc.,
// we need to increase this number so that it can contain all possible characters.
private static int CHARACTER_RANGE = 256;
public boolean isAnagramSort(String string1, String string2) {
if (string1.length() != string2.length()) {
return false;
}
char[] a1 = string1.toCharArray();
char[] a2 = string2.toCharArray();
Arrays.sort(a1);
Arrays.sort(a2);
return Arrays.equals(a1, a2);
}
public boolean isAnagramCounting(String string1, String string2) {
if (string1.length() != string2.length()) {
return false;
}
int count[] = new int[CHARACTER_RANGE];
for (int i = 0; i < string1.length(); i++) {
count[string1.charAt(i)]++;
count[string2.charAt(i)]--;
}
for (int i = 0; i < CHARACTER_RANGE; i++) {
if (count[i] != 0) {
return false;
}
}
return true;
}
public boolean isAnagramMultiset(String string1, String string2) {
if (string1.length() != string2.length()) {
return false;
}
Multiset<Character> multiset1 = HashMultiset.create();
Multiset<Character> multiset2 = HashMultiset.create();
for (int i = 0; i < string1.length(); i++) {
multiset1.add(string1.charAt(i));
multiset2.add(string2.charAt(i));
}
return multiset1.equals(multiset2);
}
public boolean isLetterBasedAnagramMultiset(String string1, String string2) {
return isAnagramMultiset(preprocess(string1), preprocess(string2));
}
private String preprocess(String source) {
return source.replaceAll("[^a-zA-Z]", "").toLowerCase();
}
}

View File

@@ -0,0 +1,72 @@
package com.baeldung.anagram;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
public class AnagramUnitTest {
@Test
public void givenAnagram_whenUsingSort_thenIdentifyAnagram() {
Anagram anagram = new Anagram();
String string1 = "abcab";
String string2 = "cabba";
assertTrue(anagram.isAnagramSort(string1, string2));
}
@Test
public void givenAnagram_whenUsingCounting_thenIdentifyAnagram() {
Anagram anagram = new Anagram();
String string1 = "abcab";
String string2 = "cabba";
assertTrue(anagram.isAnagramCounting(string1, string2));
}
@Test
public void givenAnagram_whenUsingMultiset_thenIdentifyAnagram() {
Anagram anagram = new Anagram();
String string1 = "abcab";
String string2 = "cabba";
assertTrue(anagram.isAnagramMultiset(string1, string2));
}
@Test
public void givenAnagram_whenUsingLetterBasedMultiset_thenIdentifyAnagram() {
Anagram anagram = new Anagram();
String string1 = "A decimal point";
String string2 = "Im a dot in place.";
assertTrue(anagram.isLetterBasedAnagramMultiset(string1, string2));
}
@Test
public void givenNonAnagram_whenUsingSort_thenIdentifyNotAnagram() {
Anagram anagram = new Anagram();
String string1 = "abcaba";
String string2 = "cabbac";
assertFalse(anagram.isAnagramSort(string1, string2));
}
@Test
public void givenNonAnagram_whenUsingCounting_thenIdentifyNotAnagram() {
Anagram anagram = new Anagram();
String string1 = "abcaba";
String string2 = "cabbac";
assertFalse(anagram.isAnagramCounting(string1, string2));
}
@Test
public void givenNonAnagram_whenUsingMultiset_thenIdentifyNotAnagram() {
Anagram anagram = new Anagram();
String string1 = "abcaba";
String string2 = "cabbac";
assertFalse(anagram.isAnagramMultiset(string1, string2));
}
@Test
public void ggivenNonAnagram_whenUsingLetterBasedMultiset_thenIdentifyAnagram() {
Anagram anagram = new Anagram();
String string1 = "A decimal point";
String string2 = "Im dot in place.";
assertFalse(anagram.isAnagramMultiset(string1, string2));
}
}