mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-07-14 09:22:32 +08:00
Add a new implementation for CheckAnagrams (#4231)
This commit is contained in:

committed by
GitHub

parent
2456d86432
commit
9ecc3aae59
@ -8,13 +8,6 @@ import java.util.Map;
|
|||||||
* differently (ignoring the case).
|
* differently (ignoring the case).
|
||||||
*/
|
*/
|
||||||
public class CheckAnagrams {
|
public class CheckAnagrams {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
assert isAnagrams("Silent", "Listen");
|
|
||||||
assert isAnagrams("This is a string", "Is this a string");
|
|
||||||
assert !isAnagrams("There", "Their");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if two strings are anagrams or not
|
* Check if two strings are anagrams or not
|
||||||
*
|
*
|
||||||
@ -50,4 +43,66 @@ public class CheckAnagrams {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If given strings contain Unicode symbols.
|
||||||
|
* The first 128 ASCII codes are identical to Unicode.
|
||||||
|
* This algorithm is case-sensitive.
|
||||||
|
*
|
||||||
|
* @param s1 the first string
|
||||||
|
* @param s2 the second string
|
||||||
|
* @return true if two string are anagrams, otherwise false
|
||||||
|
*/
|
||||||
|
public static boolean isAnagramsUnicode(String s1, String s2) {
|
||||||
|
int[] dict = new int[128];
|
||||||
|
for (char ch : s1.toCharArray()) {
|
||||||
|
dict[ch]++;
|
||||||
|
}
|
||||||
|
for (char ch : s2.toCharArray()) {
|
||||||
|
dict[ch]--;
|
||||||
|
}
|
||||||
|
for (int e : dict) {
|
||||||
|
if (e != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If given strings contain only lowercase English letters.
|
||||||
|
* <p>
|
||||||
|
* The main "trick":
|
||||||
|
* To map each character from the first string 's1' we need to subtract an integer value of 'a' character
|
||||||
|
* as 'dict' array starts with 'a' character.
|
||||||
|
*
|
||||||
|
* @param s1 the first string
|
||||||
|
* @param s2 the second string
|
||||||
|
* @return true if two string are anagrams, otherwise false
|
||||||
|
*/
|
||||||
|
public static boolean isAnagramsOptimised(String s1, String s2) {
|
||||||
|
// 26 - English alphabet length
|
||||||
|
int[] dict = new int[26];
|
||||||
|
for (char ch : s1.toCharArray()) {
|
||||||
|
checkLetter(ch);
|
||||||
|
dict[ch - 'a']++;
|
||||||
|
}
|
||||||
|
for (char ch : s2.toCharArray()) {
|
||||||
|
checkLetter(ch);
|
||||||
|
dict[ch - 'a']--;
|
||||||
|
}
|
||||||
|
for (int e : dict) {
|
||||||
|
if (e != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkLetter(char ch) {
|
||||||
|
int index = ch - 'a';
|
||||||
|
if (index < 0 || index >= 26) {
|
||||||
|
throw new IllegalArgumentException("Strings must contain only lowercase English letters!");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,35 +1,69 @@
|
|||||||
package com.thealgorithms.strings;
|
package com.thealgorithms.strings;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
public class CheckAnagramsTest {
|
public class CheckAnagramsTest {
|
||||||
|
private static final String MESSAGE = "Strings must contain only lowercase English letters!";
|
||||||
|
|
||||||
|
// CHECK METHOD isAnagrams()
|
||||||
@Test
|
@Test
|
||||||
public void CheckAnagrams() {
|
public void testCheckAnagrams() {
|
||||||
String testString1 = "STUDY";
|
String testString1 = "STUDY";
|
||||||
String testString2 = "DUSTY";
|
String testString2 = "DUSTY";
|
||||||
assertTrue(CheckAnagrams.isAnagrams(testString1, testString2));
|
Assertions.assertTrue(CheckAnagrams.isAnagrams(testString1, testString2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void CheckFalseAnagrams() {
|
public void testCheckFalseAnagrams() {
|
||||||
String testString1 = "STUDY";
|
String testString1 = "STUDY";
|
||||||
String testString2 = "random";
|
String testString2 = "random";
|
||||||
assertFalse(CheckAnagrams.isAnagrams(testString1, testString2));
|
Assertions.assertFalse(CheckAnagrams.isAnagrams(testString1, testString2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void CheckSameWordAnagrams() {
|
public void testCheckSameWordAnagrams() {
|
||||||
String testString1 = "STUDY";
|
String testString1 = "STUDY";
|
||||||
assertTrue(CheckAnagrams.isAnagrams(testString1, testString1));
|
Assertions.assertTrue(CheckAnagrams.isAnagrams(testString1, testString1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void CheckDifferentCasesAnagram() {
|
public void testCheckDifferentCasesAnagram() {
|
||||||
String testString1 = "STUDY";
|
String testString1 = "STUDY";
|
||||||
String testString2 = "dusty";
|
String testString2 = "dusty";
|
||||||
assertTrue(CheckAnagrams.isAnagrams(testString1, testString2));
|
Assertions.assertTrue(CheckAnagrams.isAnagrams(testString1, testString2));
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK METHOD isAnagramsUnicode()
|
||||||
|
// Below tests work with strings which consist of Unicode symbols & the algorithm is case-sensitive.
|
||||||
|
@Test
|
||||||
|
public void testStringAreValidAnagramsCaseSensitive() {
|
||||||
|
Assertions.assertTrue(CheckAnagrams.isAnagramsUnicode("Silent", "liSten"));
|
||||||
|
Assertions.assertTrue(CheckAnagrams.isAnagramsUnicode("This is a string", "is This a string"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStringAreNotAnagramsCaseSensitive() {
|
||||||
|
Assertions.assertFalse(CheckAnagrams.isAnagramsUnicode("Silent", "Listen"));
|
||||||
|
Assertions.assertFalse(CheckAnagrams.isAnagramsUnicode("This is a string", "Is this a string"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK METHOD isAnagramsOptimised()
|
||||||
|
// Below tests work with strings which consist of only lowercase English letters
|
||||||
|
@Test
|
||||||
|
public void testOptimisedAlgorithmStringsAreValidAnagrams() {
|
||||||
|
Assertions.assertTrue(CheckAnagrams.isAnagramsOptimised("silent", "listen"));
|
||||||
|
Assertions.assertTrue(CheckAnagrams.isAnagramsOptimised("mam", "amm"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOptimisedAlgorithmShouldThrowExceptionWhenStringsContainUppercaseLetters() {
|
||||||
|
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> CheckAnagrams.isAnagramsOptimised("Silent", "Listen"));
|
||||||
|
Assertions.assertEquals(exception.getMessage(), MESSAGE);
|
||||||
|
|
||||||
|
exception = assertThrows(IllegalArgumentException.class, () -> Assertions.assertFalse(CheckAnagrams.isAnagramsOptimised("This is a string", "Is this a string")));
|
||||||
|
Assertions.assertEquals(exception.getMessage(), MESSAGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user