题目: 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
Regular Expression Matching
分析: 这是一道比较难的题目. 解决思路是先看字符串s
和p
从i
和j
开始的子串是否匹配, 用递归的方法直到串的最后, 最后回溯得到结果. 假设现在走到s
的i
位置, p
的j
位置, 分以下两种情况讨论:
-
p[j+1] != '*'
: 这种情况比较直观, 直接判断s
的i
位置和'p'的'j'位置上的字符是否相同即可(如果p[j] == '.'
则认为相同). 如果不相同则返回false
, 否则递归下一层i+1
,j+1
. -
p[j+1] == '*'
: 那么此时要看从s[i]
开始的子串, 假设s[i], s[i+1]...s[i+k]
都等于p[j]
那么意味着这些都有可能是合适的匹配, 那么递归对于剩下的(i, j+2), (i+1, j+2)...(i+k, j+2)
位置进行尝试(j+2
是因为要跳过当前字符和下一个*
).
code:
class Solution {
public:
bool isMatch(string s, string p) {
return helper(s, 0, p, 0);
}
bool helper(string& s, int i, string& p, int j) {
// 看s和p从i和j开始的子串是否匹配
if(j == p.length())
return i == s.length();
// p[j+1] != '*'
if(j == p.length() - 1 || p[j+1] != '*') {
if(i == s.length() || s[i] != p[j] && p[j] != '.')
return false;
else
return helper(s, i+1, p, j+1);
}
// p[j+1] == '*'
while(i < s.length() && (s[i] == p[j] || p[j] == '.')) {
if(helper(s, i, p, j+2))
return true;
++i;
}
return helper(s, i, p, j+2);
}
};