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:
parent
f95933e870
commit
d0a9b57694
|
@ -0,0 +1,5 @@
|
|||
## Java String Algorithms
|
||||
|
||||
This module contains articles about string-related algorithms.
|
||||
|
||||
### Relevant Articles:
|
|
@ -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>
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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 = "I’m 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 = "I’m dot in place.";
|
||||
assertFalse(anagram.isAnagramMultiset(string1, string2));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue