正则表达式匹配(五十二)
题目描述:
请实现一个函数用来匹配包括.
和*
的正则表达式。模式中的字符.
表示任意一个字符,而 *
表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串”aaa”与模式”a.a”和”ab*ac*a”匹配,但是与”aa.a”和”ab*a”均不匹配.
代码(已在牛客上 AC)
这要题可以使用递归来做, 主要实现的方法是 matchCore(str, pattern)
;
在 match(str, pattern)
中:
- 如果
str
与pattern
同时为空, 那么直接返回false
;
在 matchCore(str, pattern)
中:
- 如果
str
与pattern
同时为\0
, 即都到了字符串的末尾, 说明二者完全匹配, 返回true
; - 如果
*str != '\0'
而pattern
先到结尾, 那么直接返回false
;
后面的情况就是在pattern
没有到结尾进行考虑的.
首先考虑 *(pattern + 1)
是否为 *
:
- 如果是的话, 那么就需要判断当前
*str
与*pattern
是否相等(同时要考虑*pattern
为.
的情况, 由于其为.
可以完全匹配一个字符, 因此需要保证此时*str != '\0'
).
在上面条件满足的情况下, 要考虑以下三种情况:
1.*
匹配 0 个字符, 对应matchCore(str, pattern + 2)
2.*
匹配 1 个字符, 对应matchCore(str + 1, pattern + 2)
3.*
匹配多个字符, 对应matchCore(str + 1, pattern)
而如果*str
与*pattern
不相等, 由于*
可以匹配 0 个字符, 所以可以继续进行匹配:matchCore(str, pattern + 2)
- 如果
*(pattern + 1)
不等于*
, 那么只有*str
与当前*pattern
匹配才行. - 其他情况都返回
false
.
class Solution {
public:
bool match(char* str, char* pattern) {
if (!str || !pattern) return false; // 指针为空, 返回 false;
return matchCore(str, pattern);
}
private:
bool matchCore(char *str, char *pattern) {
// 两者都到了各自的尾部, 返回 true
if (*str == '\0' && *pattern == '\0') return true;
// 如果字符串没有到尾部, 但是模式串到了结尾, 那么就返回 false;
// 但是如果字符串到了尾部, 而模式串没有到尾部的话, 还要继续判断, 因为
// 模式串结尾可能是 '*'.
if (*str != '\0' && *pattern == '\0') return false;
// 如果模式串下一个字符是 '*'
// 那么根据当前的字符 str[i] 与 pattern[j] 是否相等分为两种情况讨论:
if (*(pattern + 1) == '*') {
if (*str == *pattern || (*str != '\0' && *pattern == '.')) {
// 如果 str[i] 与 pattern[j] 相等, 那么由于pattern[j+1]=='*', 需要考虑三种情况:
// 1. '*' 匹配 0 个字符;
// 2. '*' 匹配 1 个字符
// 3. '*' 匹配多个字符
return matchCore(str, pattern + 2) || // 情形 1
matchCore(str + 1, pattern + 2) || // 情形 2
matchCore(str + 1, pattern); // 情形 3
}
// 如果 str[i] 与 pattern[j] 不相等, 那么由于 pattern[j+1]=='*',
// 就可以跳过 '*' 继续判断.
else
return matchCore(str, pattern + 2);
}
// 针对 pattern[j + 1] != '*' 的情况, 有以下两个的特殊情况, 如果:
// 1. *str 与 *pattern 相等
// 2. *str 不为 '\0' 时并且 *pattern == '.'
if (*str == *pattern || (*str != '\0' && *pattern == '.'))
return matchCore(str + 1, pattern + 1);
// 其余的情况, 直接返回 false
return false;
}
};