首先,抛开.
和*
不管,如何递归地判断两个字符串相等呢?
class Solution
{
bool isMatch(string s, string p)
{
int slen = s.length();
int plen = p.length();
if (slen == 0 && plen == 0)
return true;
char c0 = getChar(s, 0);
char p0 = getChar(p, 0);
if (match(c0, p0))
{
return isMatch(s.substr(1), p.substr(1));
}
return false;
}
//判断两个字符是否相等
bool match(char a, char b)
{
return a == b;
}
//为什么要这个函数呢,主要是为了统一处理下标越界的问题
//如果越界了,直接返回0即可
char getChar(string s, int p)
{
if (s.length() > p)
{
return s[p];
}
return 0;
}
}
根据题意,.
可根任何字符匹配,那么match
方法就要改成:
//判断两个字符是否相等
bool match(char a, char b)
{
return a == b || b == '.';
}
由于*
对前一个字符有副作用,故需要对*
进行特殊判断。尤其是[任意字符]*
可以匹配任意长度的字符串,包括空串。因此,每次处理isMatch
时,都要向后探一下接下来是否有*
:
- 如果有*,则枚举其匹配所有可能性,只要有一个返回true,则返回true
- 如果没有*, 上述代码的逻辑则不需要变
最终代码:
class Solution { public: bool isMatch(string s, string p) { int slen = s.length(); int plen = p.length(); if (slen == 0 && plen == 0) return true; char c0 = getChar(s, 0); char p0 = getChar(p, 0), p1 = getChar(p, 1); if (match(c0, p0) || p1 == '*') { if (p1 != '*') { if (slen == 0) return false; return isMatch(s.substr(1), p.substr(1)); } // if p1 is *, * means 0 ~ n int i = 0; bool ret = isMatch(s.substr(0), p.substr(2)); // try 0 if (ret) return ret; while (i < slen && match(getChar(s, i), p0)) { ret = isMatch(s.substr(i+1), p.substr(2)); // try for every available position if (ret) return ret; i++; } } return false; } bool match(char a, char b) { return a == b || b == '.'; } char getChar(string s, int p) { if (s.length() > p) { return s[p]; } return 0; } };
此算法实际运行复杂度较高,leetcode上15.44%,但是个中知识值得细细咀嚼。
整理自:https://segmentfault.com/a/1190000000453572
如有不当之处,请联系我:clark_lee0806@foxmail.com