Problem: Given an input string s and a pattern p, implement regular expression matching with support for '.' and '*' where:
- '.' Matches any single character.
- '*' Matches zero or more of the preceding element.
The matching should cover the entire input string (not partial).
Example:
Input: s = "aa", p = "a" Output: false Explanation: "a" does not match the entire string "aa".
Input: s = "aa", p = "a*" Output: true Explanation: '*' means zero or more of the preceding element, 'a'. Therefore, by repeating 'a' once, it becomes "aa".
Input: s = "ab", p = ".*" Output: true Explanation: ".*" means "zero or more (*) of any character (.)".
Approach: Use DP. Have a table [s.Length + 1][p.Length + 1] where table[i][j] indicates s(0..i-1) is a match of pattern p(0...j-1). Once we fill this we need to return table[s.Length][p.Length]. Here is how to fill this table -
- If pattern and string both are null then its a match so table[0][0] is always true.
- If pattern is null (p.Length = 0) then its a mismatch so table[i][0] = false for i = 1...s.Length.
- If string is null then table[0][j] can be true only if pattern has p[j - 1] = '*' and table[0, j - 2] is true for j = 1...p.Length
- table[i][j] = table[i-1][j-1] if current pattern character i.e. p[j - 1] is either . or match with current char of string i.e. s[i-1]
- If p[j - 1] is '*' then
- a. if previous char in pattern match current char of s i.e. p[j - 2] is '.' or s[i-1] then table[i][j] = table[i][j-2] || table[i-1][j]
- if not then table[i][j] = table[i][j-2]
- table[i][j] = false.
Implementation in C#:
public bool IsRegexMatch(string s, string p)
{
bool[,] lookup = new bool[s.Length + 1, p.Length + 1];
lookup[0, 0] = true;
for (int i = 1; i <= p.Length; ++i)
{
if (p[i - 1] == '*')
{
lookup[0, i] = i - 2 >= 0 ? lookup[0, i - 2] :false;
}
}
for (int i = 1; i <= s.Length; ++i)
{
for (int j = 1; j <= p.Length; ++j)
{
if (p[j - 1] == '*')
{
lookup[i, j] = lookup[i, j - 2];
if (p[j - 2] == '.' || p[j - 2] == s[i - 1])
{
lookup[i, j] = lookup[i, j - 2] || lookup[i - 1, j];
}
}
else if (p[j - 1] == '.' || s[i - 1] == p[j - 1])
{
lookup[i, j] = lookup[i - 1, j - 1];
}
else
{
lookup[i, j] = false;
}
}
}
return lookup[s.Length, p.Length];
}
Complexity: O(m * n)
No comments:
Post a Comment