Skip to content

Commit 435532f

Browse files
authored
Add WordPatternMatcher algorithm (#5627)
1 parent d3bd287 commit 435532f

File tree

3 files changed

+128
-0
lines changed

3 files changed

+128
-0
lines changed

DIRECTORY.md

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
* [Permutation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/Permutation.java)
2020
* [PowerSum](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/PowerSum.java)
2121
* [SubsequenceFinder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/SubsequenceFinder.java)
22+
* [WordPatternMatcher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/WordPatternMatcher.java)
2223
* [WordSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/WordSearch.java)
2324
* bitmanipulation
2425
* [BitSwap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java)
@@ -624,6 +625,7 @@
624625
* [PermutationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/PermutationTest.java)
625626
* [PowerSumTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/PowerSumTest.java)
626627
* [SubsequenceFinderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/SubsequenceFinderTest.java)
628+
* [WordPatternMatcherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/WordPatternMatcherTest.java)
627629
* [WordSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/WordSearchTest.java)
628630
* bitmanipulation
629631
* [BitSwapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package com.thealgorithms.backtracking;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
/**
7+
* Class to determine if a pattern matches a string using backtracking.
8+
*
9+
* Example:
10+
* Pattern: "abab"
11+
* Input String: "JavaPythonJavaPython"
12+
* Output: true
13+
*
14+
* Pattern: "aaaa"
15+
* Input String: "JavaJavaJavaJava"
16+
* Output: true
17+
*
18+
* Pattern: "aabb"
19+
* Input String: "JavaPythonPythonJava"
20+
* Output: false
21+
*/
22+
public final class WordPatternMatcher {
23+
private WordPatternMatcher() {
24+
}
25+
26+
/**
27+
* Determines if the given pattern matches the input string using backtracking.
28+
*
29+
* @param pattern The pattern to match.
30+
* @param inputString The string to match against the pattern.
31+
* @return True if the pattern matches the string, False otherwise.
32+
*/
33+
public static boolean matchWordPattern(String pattern, String inputString) {
34+
Map<Character, String> patternMap = new HashMap<>();
35+
Map<String, Character> strMap = new HashMap<>();
36+
return backtrack(pattern, inputString, 0, 0, patternMap, strMap);
37+
}
38+
39+
/**
40+
* Backtracking helper function to check if the pattern matches the string.
41+
*
42+
* @param pattern The pattern string.
43+
* @param inputString The string to match against the pattern.
44+
* @param patternIndex Current index in the pattern.
45+
* @param strIndex Current index in the input string.
46+
* @param patternMap Map to store pattern characters to string mappings.
47+
* @param strMap Map to store string to pattern character mappings.
48+
* @return True if the pattern matches, False otherwise.
49+
*/
50+
private static boolean backtrack(String pattern, String inputString, int patternIndex, int strIndex, Map<Character, String> patternMap, Map<String, Character> strMap) {
51+
if (patternIndex == pattern.length() && strIndex == inputString.length()) {
52+
return true;
53+
}
54+
if (patternIndex == pattern.length() || strIndex == inputString.length()) {
55+
return false;
56+
}
57+
58+
char currentChar = pattern.charAt(patternIndex);
59+
if (patternMap.containsKey(currentChar)) {
60+
String mappedStr = patternMap.get(currentChar);
61+
if (inputString.startsWith(mappedStr, strIndex)) {
62+
return backtrack(pattern, inputString, patternIndex + 1, strIndex + mappedStr.length(), patternMap, strMap);
63+
} else {
64+
return false;
65+
}
66+
}
67+
68+
for (int end = strIndex + 1; end <= inputString.length(); end++) {
69+
String substring = inputString.substring(strIndex, end);
70+
if (strMap.containsKey(substring)) {
71+
continue;
72+
}
73+
74+
patternMap.put(currentChar, substring);
75+
strMap.put(substring, currentChar);
76+
if (backtrack(pattern, inputString, patternIndex + 1, end, patternMap, strMap)) {
77+
return true;
78+
}
79+
80+
patternMap.remove(currentChar);
81+
strMap.remove(substring);
82+
}
83+
84+
return false;
85+
}
86+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.thealgorithms.backtracking;
2+
3+
import static org.junit.jupiter.api.Assertions.assertFalse;
4+
import static org.junit.jupiter.api.Assertions.assertTrue;
5+
6+
import org.junit.jupiter.api.Test;
7+
8+
public class WordPatternMatcherTest {
9+
10+
@Test
11+
public void testPatternMatchingSuccess() {
12+
assertTrue(WordPatternMatcher.matchWordPattern("aba", "GraphTreesGraph"));
13+
assertTrue(WordPatternMatcher.matchWordPattern("xyx", "PythonRubyPython"));
14+
}
15+
16+
@Test
17+
public void testPatternMatchingFailure() {
18+
assertFalse(WordPatternMatcher.matchWordPattern("GG", "PythonJavaPython"));
19+
}
20+
21+
@Test
22+
public void testEmptyPatternAndString() {
23+
assertTrue(WordPatternMatcher.matchWordPattern("", ""));
24+
}
25+
26+
@Test
27+
public void testEmptyPattern() {
28+
assertFalse(WordPatternMatcher.matchWordPattern("", "nonempty"));
29+
}
30+
31+
@Test
32+
public void testEmptyString() {
33+
assertFalse(WordPatternMatcher.matchWordPattern("abc", ""));
34+
}
35+
36+
@Test
37+
public void testLongerPatternThanString() {
38+
assertFalse(WordPatternMatcher.matchWordPattern("abcd", "abc"));
39+
}
40+
}

0 commit comments

Comments
 (0)