题目:简单正则表达式匹配
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
对于'.'字符,不需要什么考虑
对于'*'字符,把它与前面的字符作为一个整体
递归求解问题
重载函数,表示字符串s从si开始的部分是否与字符串p从pi开始的部分匹配
bool isMatch(const char *s, const char *p, int si, int pi)
如果p中的一个字符ch后面有'*',那么看s从si开始有多少个连续的ch,若数目为n,则ch的数量范围为[0, n]
如果ch后面没有'*',则ch的数量为1
尝试ch的每一个数量,看是否能够匹配
在失败匹配下,算法要遍历所有的可能
最开始也是同样的思路,但是使用string进行操作
不断地复制修改成新字符串,递归到最深处无'*'时才进行比较
对于*可代替的数量范围是[0,s.size()],结果超时了n久
class Solution {
public:
bool isMatch(const char *s, const char *p, int si, int pi) {
if (s[si] == '\0' && p[pi] == '\0') { // 匹配成功
return true;
}
if (p[pi + 1] != '\0' && p[pi + 1] == '*') { // p[pi]后有‘*’
if (s[si] != p[pi] && p[pi] != '.') { // 字符不对应,则跳到p的下两个字符
return isMatch(s, p, si, pi + 2);
} else {
int count = 0;
bool res = false;
if (p[pi] != '.') {
for (int j = si; s[j] != '\0' && s[si] == s[j]; j++) {
count++;
}
} else {
count = strlen(s) - si;
}
for (int j = 0; j <= count; j++) { // 尝试每一种可能
res = res || isMatch(s, p, si + j, pi + 2);
if (res) { break; }
}
return res;
}
} else { // p[pi]后没有‘*’
if (s[si] != p[pi] && p[pi] != '.') { // 字符不对应,匹配失败
return false;
} else {
return isMatch(s, p, si + 1, pi + 1);
}
}
}
bool isMatch(string s, string p) {
const char *cs = s.c_str(), *cp = p.c_str();
return isMatch(cs, cp, 0, 0);
}
};
>,< 好半天