该题和wildcard matching类似,但是*意义改变
题意:Implement regular expression matching with support for ‘.’ and ‘*’.
‘.’ Matches any single character.
‘*’ Matches zero or more of the preceding element.The matching should cover the entire input string (not partial).
The function prototype should be:
bool isMatch(const char *s, const char *p)Some examples:
isMatch(“aa”,”a”) → false
isMatch(“aa”,”aa”) → true
isMatch(“aaa”,”aa”) → false
isMatch(“aa”, “a*”) → true
isMatch(“aa”, “.*”) → true
isMatch(“ab”, “.*”) → true
isMatch(“aab”, “c*a*b”) → true
解法1,递归
字符串s,p,p为可能带*.的字符串
边界条件:p为空时
- 第二个字符是*:有两种情况会匹配,用x表示第一个字符
- x*表示空,s和除去开头两个字符的p匹配
- x*不表示空,即x至少匹配1个字符。x与s的第一个字符匹配,且除去第一个字符的s与p匹配
- 第二个字符不是*:直接匹配开头字符,然后匹配除去开头的s和除去开头的p
bool isMatch(string s, string p) {
if(p.empty()) return s.empty();
if(p[1] == '*')
return isMatch(s, p.substr(2)) || !s.empty() && (s[0] == p[0] || p[0] == '.') && isMatch(s.substr(1), p);
else return !s.empty() && (s[0] == p[0] || p[0] == '.') && isMatch(s.substr(1), p.substr(1));
}
解法2,DP
f[i][j] 为真 表示字符串s[0,···,i-1]和p[0,···,j-1]匹配。
当p[j-1]为*时:
1. x*表示空,
2. x*至少匹配1个字符
即:f[i][j]= f[i][j-2] or ( f[i-1][j] and s[i-1] 匹配 p[j-2])
左边即为表示空的情况,右边为匹配至少1个字符的情况。
当p[j-1]不为*时:
f[i][j]=f[i-1][j-1] and s[i-1]匹配p[j-1]
bool isMatch(string s, string p){
int len1 = s.size();
int len2 = p.size();
bool dp[len1+1][len2+1];
dp[0][0] = true;
for(int i = 1; i <= len1; ++i)
dp[i][0] = false;
for(int i = 1; i <= len2; ++i)
dp[0][i] = i > 1 && p[i-1] == '*' && dp[0][i-2];
for(int i = 1; i <= len1; ++i)
for(int j = 1; j <= len2; ++j)
if(p[j-1] == '*')
dp[i][j] = dp[i][j-2] || dp[i-1][j] && (s[i-1] == p[j-2] || p[j-2] == '.');
else
dp[i][j] = dp[i-1][j-1] && (s[i-1] == p[j-1] || p[j-1] == '.');
return dp[len1][len2];
}