对于leetcode上这个题目,我用了不少时间来消化。
题目大意如下:
实现两个字符串s,t的匹配,其中t字符串中的
‘.’ 能匹配任何一个字符.
‘*’ 能充当0个或者多个前面一个字符.
匹配结果要覆盖整个字符串
几个例子:
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
比如说最后这个例子c*a*b 能够和aab匹配 就说明第一个* 充当了0个c,第二个 *充当了两个a。
该题有两种较为普遍的解法:递归和动规。以下我就两种方法进行简要的分析。
该题的一个难点就是当t字符串中出现了符号“ * ”时该如何处理,有时候一下子并不能够清晰的把代码给写出来。我们可以直观地想,出现“ * ”时,该“ * ”可以充当0个,1个,2个…前面的字符,充当的过程还需要满足条件 (s[i]==p[0]) 或者(p[i]==’.’ && s[i]!=’\0’)。 我们将每种可能都与s串进行一遍比较,若有一种可以匹配成功,即是匹配成功。
若t字符串中的当前匹配符号不是符号“ * ”就好办多了,我们直接对 s[i]==p[0] 或者 p[0]==’.’ 进行判断,若匹配成功,那么就可以进行下一步匹配。
参考代码如下:(参考别人)
//递归方法
bool isMatch(string s, string p)
{
if ( p.empty() ) return s.empty();
// p[1]不是*
if ( p[1]!=‘*‘ )
{
return ( s[0]==p[0] || (p[0]==‘.‘ && !s.empty()) ) && isMatch(s.substr(1), p.substr(1));
}
// p[1]是*
int i = 0;
for ( ; s[i]==p[0] || (p[0]==‘.‘ && i<s.size()); ++i)
{// * 可以充当0个,1个,2个...p[0] 但必须满足匹配条件
if ( isMatch(s.substr(i), p.substr(2)) ) return true;
}
// p[1] 是 * 但是 p[0] != s[i]
return isMatch(s.substr(i), p.substr(2));
}
若是对动态规划较为熟悉的人可能对于该方法可能更顺手些。
我们提供一个二维空间集合f[i][j] 其表示字符串s[0..i-1]能否和t[0…j-1]匹配成功,我们很快可以得到动态规划转移方程
这个很好理解,s[i-1]和t[j-1]若相同,那么其s[0…i-2] 至 t[0…j-2]仍然能匹配成功时,那么这两段字符串就是匹配成功。
上述动规方程中的 f[i - 1][j] 包含了 t[j-1]充当2个,3个…多个t[j-2] 的所有可能性,并且动规过程中,我们已经计算并保存了结果。
参考代码如下:(参考别人)
bool isMatch(string s, string p) {
int m = s.size(), n = p.size();
vector<vector<bool>> f(m + 1, vector<bool>(n + 1, false));
f[0][0] = true;//空串与空串匹配成功
for (int i = 1; i <= m; i++)//s串与空串匹配结果为false
f[i][0] = false;
// p[0..j - 1] 能与空串匹配 需满足 p[j - 1]==‘*‘ 并且 p[0..j - 3] 能与空串匹配
for (int j = 1; j <= n; j++)
f[0][j] = j > 1 && ‘*‘ == p[j - 1] && f[0][j - 2];
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++)
if (p[j - 1] != ‘*‘)
f[i][j] = f[i - 1][j - 1] && (s[i - 1] == p[j - 1] || ‘.‘ == p[j - 1]);
else
f[i][j] = f[i][j - 2] || (s[i - 1] == p[j - 2] || ‘.‘ == p[j - 2]) && f[i - 1][j];
return f[m][n];
}
两种方法不同的思想,其中有相通的部分,都能解决问题,记录一下以便以后回顾。
版权声明:本文为博主原创文章,未经博主允许不得转载。
Leetcode : Regular Expression Matching
原文地址:http://blog.csdn.net/zhaoyunfullmetal/article/details/46794377