Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
* [Permutation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/Permutation.java)
* [PowerSum](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/PowerSum.java)
* [SubsequenceFinder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/SubsequenceFinder.java)
* [WordPatternMatcher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/WordPatternMatcher.java)
* [WordSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/WordSearch.java)
* bitmanipulation
* [BitSwap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java)
Expand Down Expand Up @@ -624,6 +625,7 @@
* [PermutationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/PermutationTest.java)
* [PowerSumTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/PowerSumTest.java)
* [SubsequenceFinderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/SubsequenceFinderTest.java)
* [WordPatternMatcherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/WordPatternMatcherTest.java)
* [WordSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/WordSearchTest.java)
* bitmanipulation
* [BitSwapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package com.thealgorithms.backtracking;

import java.util.HashMap;
import java.util.Map;

/**
* Class to determine if a pattern matches a string using backtracking.
*
* Example:
* Pattern: "abab"
* Input String: "JavaPythonJavaPython"
* Output: true
*
* Pattern: "aaaa"
* Input String: "JavaJavaJavaJava"
* Output: true
*
* Pattern: "aabb"
* Input String: "JavaPythonPythonJava"
* Output: false
*/
public final class WordPatternMatcher {
private WordPatternMatcher() {
}

/**
* Determines if the given pattern matches the input string using backtracking.
*
* @param pattern The pattern to match.
* @param inputString The string to match against the pattern.
* @return True if the pattern matches the string, False otherwise.
*/
public static boolean matchWordPattern(String pattern, String inputString) {
Map<Character, String> patternMap = new HashMap<>();
Map<String, Character> strMap = new HashMap<>();
return backtrack(pattern, inputString, 0, 0, patternMap, strMap);
}

/**
* Backtracking helper function to check if the pattern matches the string.
*
* @param pattern The pattern string.
* @param inputString The string to match against the pattern.
* @param patternIndex Current index in the pattern.
* @param strIndex Current index in the input string.
* @param patternMap Map to store pattern characters to string mappings.
* @param strMap Map to store string to pattern character mappings.
* @return True if the pattern matches, False otherwise.
*/
private static boolean backtrack(String pattern, String inputString, int patternIndex, int strIndex, Map<Character, String> patternMap, Map<String, Character> strMap) {
if (patternIndex == pattern.length() && strIndex == inputString.length()) {
return true;
}
if (patternIndex == pattern.length() || strIndex == inputString.length()) {
return false;
}

char currentChar = pattern.charAt(patternIndex);
if (patternMap.containsKey(currentChar)) {
String mappedStr = patternMap.get(currentChar);
if (inputString.startsWith(mappedStr, strIndex)) {
return backtrack(pattern, inputString, patternIndex + 1, strIndex + mappedStr.length(), patternMap, strMap);
} else {
return false;
}
}

for (int end = strIndex + 1; end <= inputString.length(); end++) {
String substring = inputString.substring(strIndex, end);
if (strMap.containsKey(substring)) {
continue;
}

patternMap.put(currentChar, substring);
strMap.put(substring, currentChar);
if (backtrack(pattern, inputString, patternIndex + 1, end, patternMap, strMap)) {
return true;
}

patternMap.remove(currentChar);
strMap.remove(substring);
}

return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.thealgorithms.backtracking;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.Test;

public class WordPatternMatcherTest {

@Test
public void testPatternMatchingSuccess() {
assertTrue(WordPatternMatcher.matchWordPattern("aba", "GraphTreesGraph"));
assertTrue(WordPatternMatcher.matchWordPattern("xyx", "PythonRubyPython"));
}

@Test
public void testPatternMatchingFailure() {
assertFalse(WordPatternMatcher.matchWordPattern("GG", "PythonJavaPython"));
}

@Test
public void testEmptyPatternAndString() {
assertTrue(WordPatternMatcher.matchWordPattern("", ""));
}

@Test
public void testEmptyPattern() {
assertFalse(WordPatternMatcher.matchWordPattern("", "nonempty"));
}

@Test
public void testEmptyString() {
assertFalse(WordPatternMatcher.matchWordPattern("abc", ""));
}

@Test
public void testLongerPatternThanString() {
assertFalse(WordPatternMatcher.matchWordPattern("abcd", "abc"));
}
}
Loading