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
这道题的难度较大,虽然思路很简单,就是对两个字符串按规则进行比对。
p和s的匹配可以分为两种,一种是 p[i + 1] == '*', 另一种则是 p[i + 1] != '*'。我们需要优先考虑第二种类型,当p中没有第二种类型的子串可以对s进行匹配时,才考虑第一种类型,这很容易证明,例如 s = "a", p = " a*a"时,若优先匹配第一种类型,则应返回false,然而这明显是不正确的。
因为需要优先考虑第二种类型,这就表示我们不能简单地将两个字符串遍历比对一边,需要利用递归实现回溯操作。
class Solution {
public:
bool charMatch(char a, char b) {
if (a == b || a == '.') {
return true;
}
return false;
}
bool match(string p, string s, int i, int j) {
if (i == p.length()) {
if (j == s.length()) {
return true;
} else {
return false;
}
}
if (i + 1 < p.length() && p[i + 1] == '*') {
while (j < s.length() && charMatch(p[i], s[j])) {
if (match(p, s, i + 2, j)) {
return true;
}
j++;
}
return match(p, s, i + 2, j);
} else {
if (charMatch(p[i], s[j])) {
return match(p, s, i + 1, j + 1);
} else {
return false;
}
}
}
bool isMatch(string s, string p) {
return match(p, s, 0, 0);
}
};