Repository: TheAlgorithms/Java
Pull request #6290 (2025-06-11 16:42:22)

Chore/cleanup
<!--
Thank you for your contribution!
In order to reduce the number of notifications sent to the maintainers, please:
- create your PR as draft, cf. https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests#draft-pull-requests,
- make sure that all of the CI checks pass,
- mark your PR as ready for review, cf. https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/changing-the-stage-of-a-pull-request#marking-a-pull-request-as-ready-for-review
-->

<!-- For completed items, change [ ] to [x] -->

- [x] I have read [CONTRIBUTING.md](https://github.com/TheAlgorithms/Java/blob/master/CONTRIBUTING.md).
- [x] This pull request is all my own work -- I have not plagiarized it.
- [x] All filenames are in PascalCase.
- [x] All functions and variable names follow Java naming conventions.
- [x] All new algorithms have a URL in their comments that points to Wikipedia or other similar explanations.
- [x] All new code is formatted with `clang-format -i --style=file path/to/your/file.java`


Patch:
diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/UniquePaths.java b/src/main/java/com/thealgorithms/dynamicprogramming/UniquePaths.java
index 80b553f2..22ad8a7d 100644
--- a/src/main/java/com/thealgorithms/dynamicprogramming/UniquePaths.java
+++ b/src/main/java/com/thealgorithms/dynamicprogramming/UniquePaths.java
@@ -1,3 +1,7 @@
+package com.thealgorithms.dynamicprogramming;
+
+import java.util.Arrays;
+
 /**
  * Author: Siddhant Swarup Mallick
  * Github: https://github.com/siddhant2002
@@ -12,11 +16,6 @@
  * This program calculates the number of unique paths possible for a robot to reach the bottom-right corner
  * of an m x n grid using dynamic programming.
  */
-
-package com.thealgorithms.dynamicprogramming;
-
-import java.util.Arrays;
-
 public final class UniquePaths {
 
     private UniquePaths() {
diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java b/src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java
index 8e8bf3cc..8658ea30 100644
--- a/src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java
+++ b/src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java
@@ -1,3 +1,5 @@
+package com.thealgorithms.dynamicprogramming;
+
 /**
  *
  * Author: Janmesh Singh
@@ -11,9 +13,6 @@
  * Use DP to return True if the pattern matches the entire text and False otherwise
  *
  */
-
-package com.thealgorithms.dynamicprogramming;
-
 public final class WildcardMatching {
     private WildcardMatching() {
     }
diff --git a/src/main/java/com/thealgorithms/maths/DudeneyNumber.java b/src/main/java/com/thealgorithms/maths/DudeneyNumber.java
index acf1e55d..37f28e18 100644
--- a/src/main/java/com/thealgorithms/maths/DudeneyNumber.java
+++ b/src/main/java/com/thealgorithms/maths/DudeneyNumber.java
@@ -1,11 +1,11 @@
+package com.thealgorithms.maths;
+
 /**
  * A number is said to be Dudeney if the sum of the digits, is the cube root of the entered number.
  * Example- Let the number be 512, its sum of digits is 5+1+2=8. The cube root of 512 is also 8.
  *          Since, the sum of the digits is equal to the cube root of the entered number;
  *          it is a Dudeney Number.
  */
-package com.thealgorithms.maths;
-
 public final class DudeneyNumber {
     private DudeneyNumber() {
     }
diff --git a/src/main/java/com/thealgorithms/scheduling/RRScheduling.java b/src/main/java/com/thealgorithms/scheduling/RRScheduling.java
index 110c9741..05efe1d5 100644
--- a/src/main/java/com/thealgorithms/scheduling/RRScheduling.java
+++ b/src/main/java/com/thealgorithms/scheduling/RRScheduling.java
@@ -1,7 +1,3 @@
-/**
- * @author Md Asif Joardar
- */
-
 package com.thealgorithms.scheduling;
 
 import com.thealgorithms.devutils.entities.ProcessDetails;
@@ -11,6 +7,7 @@ import java.util.List;
 import java.util.Queue;
 
 /**
+ * @author Md Asif Joardar
  * The Round-robin scheduling algorithm is a kind of preemptive First come, First Serve CPU
  * Scheduling algorithm. This can be understood here -
  * https://www.scaler.com/topics/round-robin-scheduling-in-os/
diff --git a/src/main/java/com/thealgorithms/strings/Anagrams.java b/src/main/java/com/thealgorithms/strings/Anagrams.java
index 4b24979e..5b97af07 100644
--- a/src/main/java/com/thealgorithms/strings/Anagrams.java
+++ b/src/main/java/com/thealgorithms/strings/Anagrams.java
@@ -23,7 +23,9 @@ public final class Anagrams {
      * @param t the second string
      * @return true if the strings are anagrams, false otherwise
      */
-    public static boolean approach1(String s, String t) {
+    public static boolean areAnagramsBySorting(String s, String t) {
+        s = s.toLowerCase().replaceAll("[^a-z]", "");
+        t = t.toLowerCase().replaceAll("[^a-z]", "");
         if (s.length() != t.length()) {
             return false;
         }
@@ -43,17 +45,18 @@ public final class Anagrams {
      * @param t the second string
      * @return true if the strings are anagrams, false otherwise
      */
-    public static boolean approach2(String s, String t) {
-        if (s.length() != t.length()) {
-            return false;
+    public static boolean areAnagramsByCountingChars(String s, String t) {
+        s = s.toLowerCase().replaceAll("[^a-z]", "");
+        t = t.toLowerCase().replaceAll("[^a-z]", "");
+        int[] dict = new int[128];
+        for (char ch : s.toCharArray()) {
+            dict[ch]++;
         }
-        int[] charCount = new int[26];
-        for (int i = 0; i < s.length(); i++) {
-            charCount[s.charAt(i) - 'a']++;
-            charCount[t.charAt(i) - 'a']--;
+        for (char ch : t.toCharArray()) {
+            dict[ch]--;
         }
-        for (int count : charCount) {
-            if (count != 0) {
+        for (int e : dict) {
+            if (e != 0) {
                 return false;
             }
         }
@@ -70,7 +73,9 @@ public final class Anagrams {
      * @param t the second string
      * @return true if the strings are anagrams, false otherwise
      */
-    public static boolean approach3(String s, String t) {
+    public static boolean areAnagramsByCountingCharsSingleArray(String s, String t) {
+        s = s.toLowerCase().replaceAll("[^a-z]", "");
+        t = t.toLowerCase().replaceAll("[^a-z]", "");
         if (s.length() != t.length()) {
             return false;
         }
@@ -96,7 +101,9 @@ public final class Anagrams {
      * @param t the second string
      * @return true if the strings are anagrams, false otherwise
      */
-    public static boolean approach4(String s, String t) {
+    public static boolean areAnagramsUsingHashMap(String s, String t) {
+        s = s.toLowerCase().replaceAll("[^a-z]", "");
+        t = t.toLowerCase().replaceAll("[^a-z]", "");
         if (s.length() != t.length()) {
             return false;
         }
@@ -123,7 +130,9 @@ public final class Anagrams {
      * @param t the second string
      * @return true if the strings are anagrams, false otherwise
      */
-    public static boolean approach5(String s, String t) {
+    public static boolean areAnagramsBySingleFreqArray(String s, String t) {
+        s = s.toLowerCase().replaceAll("[^a-z]", "");
+        t = t.toLowerCase().replaceAll("[^a-z]", "");
         if (s.length() != t.length()) {
             return false;
         }
diff --git a/src/main/java/com/thealgorithms/strings/CheckAnagrams.java b/src/main/java/com/thealgorithms/strings/CheckAnagrams.java
deleted file mode 100644
index 7bf7cd9a..00000000
--- a/src/main/java/com/thealgorithms/strings/CheckAnagrams.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package com.thealgorithms.strings;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Two strings are anagrams if they are made of the same letters arranged
- * differently (ignoring the case).
- */
-public final class CheckAnagrams {
-    private CheckAnagrams() {
-    }
-    /**
-     * Check if two strings are anagrams or not
-     *
-     * @param s1 the first string
-     * @param s2 the second string
-     * @return {@code true} if two string are anagrams, otherwise {@code false}
-     */
-    public static boolean isAnagrams(String s1, String s2) {
-        int l1 = s1.length();
-        int l2 = s2.length();
-        s1 = s1.toLowerCase();
-        s2 = s2.toLowerCase();
-        Map<Character, Integer> charAppearances = new HashMap<>();
-
-        for (int i = 0; i < l1; i++) {
-            char c = s1.charAt(i);
-            int numOfAppearances = charAppearances.getOrDefault(c, 0);
-            charAppearances.put(c, numOfAppearances + 1);
-        }
-
-        for (int i = 0; i < l2; i++) {
-            char c = s2.charAt(i);
-            if (!charAppearances.containsKey(c)) {
-                return false;
-            }
-            charAppearances.put(c, charAppearances.get(c) - 1);
-        }
-
-        for (int cnt : charAppearances.values()) {
-            if (cnt != 0) {
-                return false;
-            }
-        }
-        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!");
-        }
-    }
-}


Test patch:
diff --git a/src/test/java/com/thealgorithms/strings/AnagramsTest.java b/src/test/java/com/thealgorithms/strings/AnagramsTest.java
index 88f6e0bb..fa8ea72f 100644
--- a/src/test/java/com/thealgorithms/strings/AnagramsTest.java
+++ b/src/test/java/com/thealgorithms/strings/AnagramsTest.java
@@ -13,36 +13,37 @@ public class AnagramsTest {
 
     private static Stream<AnagramTestCase> anagramTestData() {
         return Stream.of(new AnagramTestCase("late", "tale", true), new AnagramTestCase("late", "teal", true), new AnagramTestCase("listen", "silent", true), new AnagramTestCase("hello", "olelh", true), new AnagramTestCase("hello", "world", false), new AnagramTestCase("deal", "lead", true),
-            new AnagramTestCase("binary", "brainy", true), new AnagramTestCase("adobe", "abode", true), new AnagramTestCase("cat", "act", true), new AnagramTestCase("cat", "cut", false));
+            new AnagramTestCase("binary", "brainy", true), new AnagramTestCase("adobe", "abode", true), new AnagramTestCase("cat", "act", true), new AnagramTestCase("cat", "cut", false), new AnagramTestCase("Listen", "Silent", true), new AnagramTestCase("Dormitory", "DirtyRoom", true),
+            new AnagramTestCase("Schoolmaster", "TheClassroom", true), new AnagramTestCase("Astronomer", "MoonStarer", true), new AnagramTestCase("Conversation", "VoicesRantOn", true));
     }
 
     @ParameterizedTest
     @MethodSource("anagramTestData")
     void testApproach1(AnagramTestCase testCase) {
-        assertEquals(testCase.expected(), Anagrams.approach1(testCase.input1(), testCase.input2()));
+        assertEquals(testCase.expected(), Anagrams.areAnagramsBySorting(testCase.input1(), testCase.input2()));
     }
 
     @ParameterizedTest
     @MethodSource("anagramTestData")
     void testApproach2(AnagramTestCase testCase) {
-        assertEquals(testCase.expected(), Anagrams.approach2(testCase.input1(), testCase.input2()));
+        assertEquals(testCase.expected(), Anagrams.areAnagramsByCountingChars(testCase.input1(), testCase.input2()));
     }
 
     @ParameterizedTest
     @MethodSource("anagramTestData")
     void testApproach3(AnagramTestCase testCase) {
-        assertEquals(testCase.expected(), Anagrams.approach3(testCase.input1(), testCase.input2()));
+        assertEquals(testCase.expected(), Anagrams.areAnagramsByCountingCharsSingleArray(testCase.input1(), testCase.input2()));
     }
 
     @ParameterizedTest
     @MethodSource("anagramTestData")
     void testApproach4(AnagramTestCase testCase) {
-        assertEquals(testCase.expected(), Anagrams.approach4(testCase.input1(), testCase.input2()));
+        assertEquals(testCase.expected(), Anagrams.areAnagramsUsingHashMap(testCase.input1(), testCase.input2()));
     }
 
     @ParameterizedTest
     @MethodSource("anagramTestData")
     void testApproach5(AnagramTestCase testCase) {
-        assertEquals(testCase.expected(), Anagrams.approach5(testCase.input1(), testCase.input2()));
+        assertEquals(testCase.expected(), Anagrams.areAnagramsBySingleFreqArray(testCase.input1(), testCase.input2()));
     }
 }
diff --git a/src/test/java/com/thealgorithms/strings/CharacterSameTest.java b/src/test/java/com/thealgorithms/strings/CharactersSameTest.java
similarity index 100%
rename from src/test/java/com/thealgorithms/strings/CharacterSameTest.java
rename to src/test/java/com/thealgorithms/strings/CharactersSameTest.java
diff --git a/src/test/java/com/thealgorithms/strings/CheckAnagramsTest.java b/src/test/java/com/thealgorithms/strings/CheckAnagramsTest.java
deleted file mode 100644
index 82a75a13..00000000
--- a/src/test/java/com/thealgorithms/strings/CheckAnagramsTest.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package com.thealgorithms.strings;
-
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-public class CheckAnagramsTest {
-    private static final String MESSAGE = "Strings must contain only lowercase English letters!";
-
-    // CHECK METHOD isAnagrams()
-    @Test
-    public void testCheckAnagrams() {
-        String testString1 = "STUDY";
-        String testString2 = "DUSTY";
-        Assertions.assertTrue(CheckAnagrams.isAnagrams(testString1, testString2));
-    }
-
-    @Test
-    public void testCheckFalseAnagrams() {
-        String testString1 = "STUDY";
-        String testString2 = "random";
-        Assertions.assertFalse(CheckAnagrams.isAnagrams(testString1, testString2));
-    }
-
-    @Test
-    public void testCheckSameWordAnagrams() {
-        String testString1 = "STUDY";
-        Assertions.assertTrue(CheckAnagrams.isAnagrams(testString1, testString1));
-    }
-
-    @Test
-    public void testCheckDifferentCasesAnagram() {
-        String testString1 = "STUDY";
-        String testString2 = "dusty";
-        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);
-    }
-}