From 4ff775df92a3644b39fabc772fa94fca4a6a9132 Mon Sep 17 00:00:00 2001 From: ShyamChavda005 Date: Sat, 14 Mar 2026 18:18:19 +0530 Subject: [PATCH 1/5] feat(strings): add MoveHashToEnd algorithm with tests - Add MoveHashToEnd utility class that moves all '#' characters to the end of a string while preserving the order of other characters - Algorithm runs in O(n) time and O(n) space using a two-pass approach: first collects non-'#' chars, then fills remaining positions with '#' - Add null and empty string guards - Add MoveHashToEndTest with 9 unit tests covering normal, edge, and boundary cases (null, empty, all-hash, no-hash, single char) --- .../strings/MoveHashToEndTest.java | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/test/java/com/thealgorithms/strings/MoveHashToEndTest.java diff --git a/src/test/java/com/thealgorithms/strings/MoveHashToEndTest.java b/src/test/java/com/thealgorithms/strings/MoveHashToEndTest.java new file mode 100644 index 000000000000..538fbb61fc81 --- /dev/null +++ b/src/test/java/com/thealgorithms/strings/MoveHashToEndTest.java @@ -0,0 +1,54 @@ +package com.thealgorithms.strings; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +import org.junit.jupiter.api.Test; + +public class MoveHashToEndTest { + + @Test + void testBasicCase() { + assertEquals("hello###", MoveHashToEnd.moveHashToEnd("h#e#l#llo")); + } + + @Test + void testNoHash() { + assertEquals("hello", MoveHashToEnd.moveHashToEnd("hello")); + } + + @Test + void testAllHashes() { + assertEquals("###", MoveHashToEnd.moveHashToEnd("###")); + } + + @Test + void testHashAtEnd() { + assertEquals("hello#", MoveHashToEnd.moveHashToEnd("hello#")); + } + + @Test + void testHashAtStart() { + assertEquals("hello#", MoveHashToEnd.moveHashToEnd("#hello")); + } + + @Test + void testEmptyString() { + assertEquals("", MoveHashToEnd.moveHashToEnd("")); + } + + @Test + void testNullInput() { + assertNull(MoveHashToEnd.moveHashToEnd(null)); + } + + @Test + void testSingleHash() { + assertEquals("#", MoveHashToEnd.moveHashToEnd("#")); + } + + @Test + void testSingleNonHashChar() { + assertEquals("a", MoveHashToEnd.moveHashToEnd("a")); + } +} From 894ea16210351176ecb9a100a168a2c73c75bf27 Mon Sep 17 00:00:00 2001 From: ShyamChavda005 Date: Sat, 14 Mar 2026 18:20:35 +0530 Subject: [PATCH 2/5] docs(strings): add reference URL to MoveHashToEnd Javadoc --- .../thealgorithms/strings/MoveHashToEnd.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/main/java/com/thealgorithms/strings/MoveHashToEnd.java diff --git a/src/main/java/com/thealgorithms/strings/MoveHashToEnd.java b/src/main/java/com/thealgorithms/strings/MoveHashToEnd.java new file mode 100644 index 000000000000..d00d85275ee2 --- /dev/null +++ b/src/main/java/com/thealgorithms/strings/MoveHashToEnd.java @@ -0,0 +1,56 @@ +package com.thealgorithms.strings; + +/** + * Moves all '#' characters to the end of the given string while preserving + * the order of the other characters. + * + * Example: + * Input : "h#e#l#llo" + * Output : "hello###" + * + * The algorithm works by iterating through the string and collecting + * all non-# characters first, then filling the remaining positions + * with '#'. + * + * Time Complexity: O(n) + * Space Complexity: O(n) + * + * @see Move all special characters to end - GeeksForGeeks + */ +public final class MoveHashToEnd { + + /** + * Private constructor to prevent instantiation of utility class. + */ + private MoveHashToEnd() { + } + + /** + * Moves all '#' characters in the input string to the end. + * + * @param str the input string containing characters and '#' + * @return a new string with all '#' characters moved to the end + */ + public static String moveHashToEnd(String str) { + if (str == null || str.isEmpty()) { + return str; + } + + char[] arr = str.toCharArray(); + int insertPos = 0; + + // Place all non-# characters at the beginning + for (char ch : arr) { + if (ch != '#') { + arr[insertPos++] = ch; + } + } + + // Fill remaining positions with '#' + while (insertPos < arr.length) { + arr[insertPos++] = '#'; + } + + return new String(arr); + } +} \ No newline at end of file From e8187a079a1c26ab1492f8db83058b75d9bff985 Mon Sep 17 00:00:00 2001 From: ShyamChavda005 Date: Sat, 14 Mar 2026 18:30:38 +0530 Subject: [PATCH 3/5] docs: add MoveHashToEnd to DIRECTORY index --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 585c634c3429..37d9b3c295e2 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -816,6 +816,7 @@ - 📄 [Lower](src/main/java/com/thealgorithms/strings/Lower.java) - 📄 [Manacher](src/main/java/com/thealgorithms/strings/Manacher.java) - 📄 [MyAtoi](src/main/java/com/thealgorithms/strings/MyAtoi.java) + - 📄 [MoveHashToEnd](src/main/java/com/thealgorithms/strings/MoveHashToEnd.java) - 📄 [Palindrome](src/main/java/com/thealgorithms/strings/Palindrome.java) - 📄 [Pangram](src/main/java/com/thealgorithms/strings/Pangram.java) - 📄 [PermuteString](src/main/java/com/thealgorithms/strings/PermuteString.java) From c372ac1aec668aa22f1a06ee254544fb7fa6ebe9 Mon Sep 17 00:00:00 2001 From: ShyamChavda005 Date: Sat, 14 Mar 2026 18:47:30 +0530 Subject: [PATCH 4/5] style(strings): add missing newline at EOF in MoveHashToEnd --- src/main/java/com/thealgorithms/strings/MoveHashToEnd.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/thealgorithms/strings/MoveHashToEnd.java b/src/main/java/com/thealgorithms/strings/MoveHashToEnd.java index d00d85275ee2..09ea795a780d 100644 --- a/src/main/java/com/thealgorithms/strings/MoveHashToEnd.java +++ b/src/main/java/com/thealgorithms/strings/MoveHashToEnd.java @@ -53,4 +53,4 @@ public static String moveHashToEnd(String str) { return new String(arr); } -} \ No newline at end of file +} From a4e248a58bf5e547459f6505000e2792201d2e2a Mon Sep 17 00:00:00 2001 From: ShyamChavda005 Date: Sat, 14 Mar 2026 20:11:05 +0530 Subject: [PATCH 5/5] test(strings): fix MoveHashToEnd expected output for sample input --- src/main/java/com/thealgorithms/strings/MoveHashToEnd.java | 2 +- src/test/java/com/thealgorithms/strings/MoveHashToEndTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/thealgorithms/strings/MoveHashToEnd.java b/src/main/java/com/thealgorithms/strings/MoveHashToEnd.java index 09ea795a780d..bd686a0c5ba0 100644 --- a/src/main/java/com/thealgorithms/strings/MoveHashToEnd.java +++ b/src/main/java/com/thealgorithms/strings/MoveHashToEnd.java @@ -6,7 +6,7 @@ * * Example: * Input : "h#e#l#llo" - * Output : "hello###" + * Output : "helllo###" * * The algorithm works by iterating through the string and collecting * all non-# characters first, then filling the remaining positions diff --git a/src/test/java/com/thealgorithms/strings/MoveHashToEndTest.java b/src/test/java/com/thealgorithms/strings/MoveHashToEndTest.java index 538fbb61fc81..016f72ff9d7f 100644 --- a/src/test/java/com/thealgorithms/strings/MoveHashToEndTest.java +++ b/src/test/java/com/thealgorithms/strings/MoveHashToEndTest.java @@ -9,7 +9,7 @@ public class MoveHashToEndTest { @Test void testBasicCase() { - assertEquals("hello###", MoveHashToEnd.moveHashToEnd("h#e#l#llo")); + assertEquals("helllo###", MoveHashToEnd.moveHashToEnd("h#e#l#llo")); } @Test