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 f95933e870
commit d0a9b57694
4 changed files with 208 additions and 0 deletions

View File

@ -0,0 +1,5 @@
## Java String Algorithms
This module contains articles about string-related algorithms.
### Relevant Articles:

View File

@ -0,0 +1,69 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>core-java-string-algorithms-3</artifactId>
<version>0.1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>core-java-string-algorithms-3</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-java</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-java</relativePath>
</parent>
<dependencies>
<!-- test scoped -->
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.1-jre</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit-jupiter-api.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>core-java-string-algorithms-3</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<compilerArgument>-parameters</compilerArgument>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<commons-lang3.version>3.8.1</commons-lang3.version>
<assertj.version>3.6.1</assertj.version>
<guava.version>27.0.1-jre</guava.version>
<junit-jupiter-api.version>5.3.1</junit-jupiter-api.version>
</properties>
</project>

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