题目要求
整体思路
我主要分了四种情况来做:
- .
- .*
- x
- x*
其中前两种以’.'开头,后两种以x开头。分别判断每种情况。
对于’.'和’x’这两种情况很容易,直接判断s和p是否相等即可。
对于带有’*'的两种情况,我采用了递归的方法。因为不知道p中的闭包表达式需要“吞掉”多少个s中的相同字符。所以我每次移动s的指针时都进行一次自我递归。将s的子串和p的子串再次传入函数进行递归判断,如果可行就返回true,如果不可行就向前移动s的指针继续判断。
有点类似于编译原理语法分析中的递归下降的分析方法:
注意上图中的c、d、e这三步,显示了一次错误的匹配后如何进行回溯
代码
bool isMatch(string &s, string &p)
{
int indexS = 0, indexP = 0;
string substrS, substrP;
while (indexP < p.size() && indexS < s.size())
{
if (p[indexP] == '.')
{
// .*
if (indexP+1 < p.size() && p[indexP+1] == '*')
{
substrP = p.substr(indexP + 2, p.size() - indexP - 2);
while (indexS < s.size())
{
substrS = s.substr(indexS, s.size() - indexS);
if (isMatch(substrS, substrP))
{
return true;
}
++indexS;
}
indexP += 2;
}
//.
else
{
++indexP;
++indexS;
}
}
else
{
//x*
if (indexP+1 < p.size() && p[indexP + 1] == '*')
{
if (indexP + 2 >= p.size())
{
substrP = "";
}
else
substrP = p.substr(indexP+2, p.size() - indexP - 2);
while (indexS < s.size() && s[indexS] == p[indexP])
{
substrS = s.substr(indexS, s.size() - indexS);
if (isMatch(substrS, substrP))
{
return true;
}
++indexS;
}
indexP += 2;
}
//x
else
{
if (p[indexP++] != s[indexS++])
{
return false;
}
}
}
}
if (indexS == s.size() && indexP == p.size())
{
return true;
}
else
{
if (indexP < p.size())
{
while (indexP < p.size())
{
//尾部剩余闭包表达式
if (indexP+1 < p.size() && p[indexP + 1] == '*')
{
indexP += 2;
}
else
return false;
}
return true;
}
else
return false;
}
}
学到了什么
1、当需要取得数组中index+1的值时,需要先判断index+1是否越界
2、用字符串函数substr取得以index开头的子串的方法:
str.substr(index, str.size()-index);
3、在循环判断条件中使用自增或者自减时,需要考虑:如果程序连一次循环都没有进,则该自增或自减运算是否合理