Skip to content

Add WordPatternMatcher.java new algorithm #5627

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Oct 8, 2024
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