Skip to content

Commit bb26138

Browse files
committed
Add Regular Expression Matching algorithm using DP with test cases
1 parent 6d51709 commit bb26138

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package com.thealgorithms.dynamicprogramming;
2+
3+
public class RegularExpressionMatching {
4+
5+
/**
6+
* Function to implement regex matching with '.' and '*'.
7+
* '.' Matches any single character
8+
* '*' Matches zero or more of the preceding element
9+
*
10+
* @param s input string
11+
* @param p pattern string
12+
* @return true if the string matches the pattern, false otherwise
13+
*/
14+
public boolean isMatch(String s, String p) {
15+
Boolean[][] memo = new Boolean[s.length() + 1][p.length() + 1];
16+
return dp(0, 0, s, p, memo);
17+
}
18+
19+
private boolean dp(int i, int j, String s, String p, Boolean[][] memo) {
20+
if (memo[i][j] != null) return memo[i][j];
21+
22+
boolean ans;
23+
if (j == p.length()) {
24+
// If pattern is finished, string must also be finished
25+
ans = (i == s.length());
26+
} else {
27+
// Check if first character matches
28+
boolean firstMatch = (i < s.length() &&
29+
(s.charAt(i) == p.charAt(j) || p.charAt(j) == '.'));
30+
31+
// Handle '*' in the pattern
32+
if (j + 1 < p.length() && p.charAt(j + 1) == '*') {
33+
// Two options:
34+
// 1. Skip the "x*" in the pattern
35+
// 2. If firstMatch is true, consume one char from string
36+
ans = dp(i, j + 2, s, p, memo) || (firstMatch && dp(i + 1, j, s, p, memo));
37+
} else {
38+
ans = firstMatch && dp(i + 1, j + 1, s, p, memo);
39+
}
40+
}
41+
42+
memo[i][j] = ans;
43+
return ans;
44+
}
45+
46+
// -----------------------
47+
// Main function with test cases
48+
// -----------------------
49+
public static void main(String[] args) {
50+
RegularExpressionMatching solution = new RegularExpressionMatching();
51+
52+
String[][] testCases = {
53+
{"aa", "a", "false"},
54+
{"aa", "a*", "true"},
55+
{"ab", ".*", "true"},
56+
{"mississippi", "mis*is*p*.", "false"},
57+
{"ab", ".*c", "false"},
58+
{"aaa", "a*a", "true"},
59+
{"aab", "c*a*b", "true"},
60+
{"", ".*", "true"},
61+
{"", "", "true"},
62+
{"abcd", "d*", "false"}
63+
};
64+
65+
System.out.println("Testing Regular Expression Matching (DP with Memoization)\n");
66+
67+
for (String[] test : testCases) {
68+
String s = test[0];
69+
String p = test[1];
70+
boolean expected = Boolean.parseBoolean(test[2]);
71+
boolean result = solution.isMatch(s, p);
72+
System.out.printf("Input: s = \"%s\", p = \"%s\" | Output: %b | Expected: %b | %s\n",
73+
s, p, result, expected, (result == expected ? "✅" : "❌"));
74+
}
75+
}
76+
}

0 commit comments

Comments
 (0)