Skip to content

Commit 13aaad2

Browse files
feat(strings): add MoveHashToEnd algorithm (#7313)
* 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) * docs(strings): add reference URL to MoveHashToEnd Javadoc * docs: add MoveHashToEnd to DIRECTORY index * style(strings): add missing newline at EOF in MoveHashToEnd * test(strings): fix MoveHashToEnd expected output for sample input
1 parent abd1c47 commit 13aaad2

File tree

3 files changed

+111
-0
lines changed

3 files changed

+111
-0
lines changed

DIRECTORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -816,6 +816,7 @@
816816
- 📄 [Lower](src/main/java/com/thealgorithms/strings/Lower.java)
817817
- 📄 [Manacher](src/main/java/com/thealgorithms/strings/Manacher.java)
818818
- 📄 [MyAtoi](src/main/java/com/thealgorithms/strings/MyAtoi.java)
819+
- 📄 [MoveHashToEnd](src/main/java/com/thealgorithms/strings/MoveHashToEnd.java)
819820
- 📄 [Palindrome](src/main/java/com/thealgorithms/strings/Palindrome.java)
820821
- 📄 [Pangram](src/main/java/com/thealgorithms/strings/Pangram.java)
821822
- 📄 [PermuteString](src/main/java/com/thealgorithms/strings/PermuteString.java)
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package com.thealgorithms.strings;
2+
3+
/**
4+
* Moves all '#' characters to the end of the given string while preserving
5+
* the order of the other characters.
6+
*
7+
* Example:
8+
* Input : "h#e#l#llo"
9+
* Output : "helllo###"
10+
*
11+
* The algorithm works by iterating through the string and collecting
12+
* all non-# characters first, then filling the remaining positions
13+
* with '#'.
14+
*
15+
* Time Complexity: O(n)
16+
* Space Complexity: O(n)
17+
*
18+
* @see <a href="https://www.geeksforgeeks.org/move-special-char-end-string-maintain-order-alphabets/">Move all special characters to end - GeeksForGeeks</a>
19+
*/
20+
public final class MoveHashToEnd {
21+
22+
/**
23+
* Private constructor to prevent instantiation of utility class.
24+
*/
25+
private MoveHashToEnd() {
26+
}
27+
28+
/**
29+
* Moves all '#' characters in the input string to the end.
30+
*
31+
* @param str the input string containing characters and '#'
32+
* @return a new string with all '#' characters moved to the end
33+
*/
34+
public static String moveHashToEnd(String str) {
35+
if (str == null || str.isEmpty()) {
36+
return str;
37+
}
38+
39+
char[] arr = str.toCharArray();
40+
int insertPos = 0;
41+
42+
// Place all non-# characters at the beginning
43+
for (char ch : arr) {
44+
if (ch != '#') {
45+
arr[insertPos++] = ch;
46+
}
47+
}
48+
49+
// Fill remaining positions with '#'
50+
while (insertPos < arr.length) {
51+
arr[insertPos++] = '#';
52+
}
53+
54+
return new String(arr);
55+
}
56+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package com.thealgorithms.strings;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertNull;
5+
6+
import org.junit.jupiter.api.Test;
7+
8+
public class MoveHashToEndTest {
9+
10+
@Test
11+
void testBasicCase() {
12+
assertEquals("helllo###", MoveHashToEnd.moveHashToEnd("h#e#l#llo"));
13+
}
14+
15+
@Test
16+
void testNoHash() {
17+
assertEquals("hello", MoveHashToEnd.moveHashToEnd("hello"));
18+
}
19+
20+
@Test
21+
void testAllHashes() {
22+
assertEquals("###", MoveHashToEnd.moveHashToEnd("###"));
23+
}
24+
25+
@Test
26+
void testHashAtEnd() {
27+
assertEquals("hello#", MoveHashToEnd.moveHashToEnd("hello#"));
28+
}
29+
30+
@Test
31+
void testHashAtStart() {
32+
assertEquals("hello#", MoveHashToEnd.moveHashToEnd("#hello"));
33+
}
34+
35+
@Test
36+
void testEmptyString() {
37+
assertEquals("", MoveHashToEnd.moveHashToEnd(""));
38+
}
39+
40+
@Test
41+
void testNullInput() {
42+
assertNull(MoveHashToEnd.moveHashToEnd(null));
43+
}
44+
45+
@Test
46+
void testSingleHash() {
47+
assertEquals("#", MoveHashToEnd.moveHashToEnd("#"));
48+
}
49+
50+
@Test
51+
void testSingleNonHashChar() {
52+
assertEquals("a", MoveHashToEnd.moveHashToEnd("a"));
53+
}
54+
}

0 commit comments

Comments
 (0)