可以用动态规划来做,
dp[i][j]表示s的前i个字符串能否被p的前j个字符串所匹配。
当s[i]==p[j] || p[j] == '.'时:
dp[i][j] = dp[i-1][j-1] // 显而易见
p[j] == '*' 时,
1. s[i] != p[j-1] // 这就意味着此时*只能匹配0次
dp[i][j] = dp[i][j-2];
2. s[i] == '.' || s[i] == p[j-1] // 意味着*可以代表匹配0次,匹配1次,匹配多次
1)dp[i][j] = dp[i][j-2] // 匹配0次
2)dp[i][j] = dp[i][j-1] // 匹配1次
3) dp[i][j] = dp[i-1][j] // 匹配多次(这里不太好理解, 实际上就是说如果dp[i-1][j]匹配了,那么s[i]也一定会被匹配)
class Solution {
public:
bool isMatch(string s, string p) {
int dp[s.length()+1][p.length()+1]; // 为了好处理空字符串的情况,多申请了空间
// dp[i+1][j+1]代表s字符串的前i个以及p字符串的前j个是否匹配
memset(dp, 0, sizeof(dp));
dp[0][0]=1; // 两个空字串的情况
for(int i=0; i<p.length(); i++)
{
dp[0][i+1] = ((p[i] == '*' && i-1 >= 0 && dp[0][i-1]) || 0); // 初始化s的子字符串为空时的情况
}
for(int i=0; i<s.length(); i++)
{
for(int j=0; j<p.length(); j++)
{
if(s[i] == p[j] || p[j] == '.')
{
dp[i+1][j+1] = dp[i][j];
}
else if(p[j] == '*')
{
dp[i+1][j+1] = (dp[i+1][j] || (j-1 >= 0 && dp[i+1][j-1]) || (j-1 >= 0 && (s[i] == p[j-1] || p[j-1] == '.') && dp[i][j+1]));
}
}
}
return dp[s.length()][p.length()];
}
};