Skip to content

Commit aa11e00

Browse files
committed
feat: add Regular Expression Matching algorithm using DP
1 parent 03697db commit aa11e00

File tree

2 files changed

+45
-49
lines changed

2 files changed

+45
-49
lines changed
Lines changed: 17 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,37 @@
11
package com.thealgorithms.dynamicprogramming;
22

3+
/**
4+
* Class for Regular Expression Matching using Dynamic Programming.
5+
*/
36
public class RegularExpressionMatching {
47

58
/**
6-
* Function to implement regex matching with '.' and '*'.
7-
* '.' Matches any single character
8-
* '*' Matches zero or more of the preceding element
9+
* Determines if the input string matches the given pattern.
910
*
10-
* @param s input string
11-
* @param p pattern string
11+
* @param s the input string
12+
* @param p the pattern string (may contain '.' and '*')
1213
* @return true if the string matches the pattern, false otherwise
1314
*/
14-
public boolean isMatch(String s, String p) {
15-
Boolean[][] memo = new Boolean[s.length() + 1][p.length() + 1];
15+
public boolean isMatch(final String s, final String p) {
16+
final Boolean[][] memo = new Boolean[s.length() + 1][p.length() + 1];
1617
return dp(0, 0, s, p, memo);
1718
}
1819

19-
private boolean dp(int i, int j, String s, String p, Boolean[][] memo) {
20-
if (memo[i][j] != null) return memo[i][j];
20+
private boolean dp(final int i, final int j, final String s, final String p, final Boolean[][] memo) {
21+
if (memo[i][j] != null) {
22+
return memo[i][j];
23+
}
2124

22-
boolean ans;
25+
final boolean ans;
2326
if (j == p.length()) {
24-
// If pattern is finished, string must also be finished
2527
ans = (i == s.length());
2628
} else {
27-
// Check if first character matches
28-
boolean firstMatch = (i < s.length() &&
29-
(s.charAt(i) == p.charAt(j) || p.charAt(j) == '.'));
29+
final boolean firstMatch = (i < s.length() && (s.charAt(i) == p.charAt(j) || p.charAt(j) == '.'));
3030

31-
// Handle '*' in the pattern
3231
if (j + 1 < p.length() && p.charAt(j + 1) == '*') {
3332
// Two options:
34-
// 1. Skip the "x*" in the pattern
35-
// 2. If firstMatch is true, consume one char from string
33+
// 1. Skip the pattern with '*'
34+
// 2. Use '*' to match one character
3635
ans = dp(i, j + 2, s, p, memo) || (firstMatch && dp(i + 1, j, s, p, memo));
3736
} else {
3837
ans = firstMatch && dp(i + 1, j + 1, s, p, memo);
@@ -42,35 +41,4 @@ private boolean dp(int i, int j, String s, String p, Boolean[][] memo) {
4241
memo[i][j] = ans;
4342
return ans;
4443
}
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-
}
44+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.thealgorithms.dynamicprogramming;
2+
3+
import static org.junit.jupiter.api.Assertions.assertFalse;
4+
import static org.junit.jupiter.api.Assertions.assertTrue;
5+
import org.junit.jupiter.api.Test;
6+
7+
/**
8+
* Test class for RegularExpressionMatching.
9+
*/
10+
public class RegularExpressionMatchingTest {
11+
12+
@Test
13+
public void testBasicCases() {
14+
final RegularExpressionMatching matcher = new RegularExpressionMatching();
15+
16+
// Test cases from the problem
17+
assertFalse(matcher.isMatch("aa", "a"));
18+
assertTrue(matcher.isMatch("aa", "a*"));
19+
assertTrue(matcher.isMatch("ab", ".*"));
20+
assertFalse(matcher.isMatch("mississippi", "mis*is*p*."));
21+
assertFalse(matcher.isMatch("ab", ".*c"));
22+
assertTrue(matcher.isMatch("aaa", "a*a"));
23+
assertTrue(matcher.isMatch("aab", "c*a*b"));
24+
assertTrue(matcher.isMatch("", ".*"));
25+
assertTrue(matcher.isMatch("", ""));
26+
assertFalse(matcher.isMatch("abcd", "d*"));
27+
}
28+
}

0 commit comments

Comments
 (0)