题意: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
思路:这题有几个地方需要注意的,首先是声明DP数组时,可以多开一行一列的空间,但是要注意,第0行相当于是用空的字符串作为s,这个需要处理,第0列的话直接赋全0就好,另外的结果大致分为三类,根据Solutions的解释:
1、P[i][j] = P[i - 1][j - 1], if p[j - 1] != '*' && (s[i - 1] == p[j - 1] || p[j - 1] == '.');
2、P[i][j] = P[i][j - 2], if p[j - 1] == '*' and the pattern repeats for 0 times;
3、P[i][j] = P[i - 1][j] && (s[i - 1] == p[j - 2] || p[j - 2] == '.'), if p[j - 1] == '*' and the pattern repeats for at least 1 times.
注意其中p[j-1]代表的是当前项,所以对于1来说就是s和p的对应项相等,则状态由前一状态决定,对于p[j-1]==’*’时,分为两类,一类是s=ac, p=a *c,另一类是s=aab, p=a *b或 . *b即可,下面的代码也是Solutions里的。
class Solution {
public:
bool isMatch(string s, string p) {
int m = s.length(), n = p.length();
vector<vector<bool> > dp(m + 1, vector<bool> (n + 1, false));
dp[0][0] = true;
for (int i = 0; i <= m; i++)
for (int j = 1; j <= n; j++)
if (p[j - 1] == '*')
dp[i][j] = dp[i][j - 2] || (i > 0 && (s[i - 1] == p[j - 2] || p[j - 2] == '.') && dp[i - 1][j]);
else dp[i][j] = i > 0 && dp[i - 1][j - 1] && (s[i - 1] == p[j - 1] || p[j - 1] == '.');
return dp[m][n];
}
};