版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/MyCodecOdecoDecodE/article/details/78026060
LeetCode题目: 10. Regular Expression Matching
原题链接:https://leetcode.com/problems/regular-expression-matching/description/
解题思路:
此题输入为两个字符串s和p,题目要求是完全匹配,即存在一种可能,使s==p。
‘.’意为随便代表一个字符。
‘*’意为可匹配一个或多个前继字符。
(PS:’*’和前面的字符结合使用 。即:”a*”=>”“,”a”,”aa”…而不是”a”,”aa”…
例如:”” == “a*b*”)
由于*有多种可能,因此用递归来解。每次遇到’*’,分为多种情况,即匹配0个,匹配1个,匹配2个….全部匹配,递归得到结果。
核心思想:
基本情况:
1.如果子字符串为空而父字符串不为空,或父字符串为空而子字符串不为空,返回false。
递归情况:
1.如果两个字符串的首字母是否相等或其中之一为’.’,父子串都递归到下一位。
2.如果父字符串为’*’,分为多种情况,各自进行递归,如果出现true,则返回true,如果全为false,则返回false
代码细节:
- 用sbegin和pbegin代替s和p字符串的当前匹配位置
- 基础情况中,如果s为空,p不为空,也有可能匹配
- ‘*’情况中,对n个重复的字符,存在n+1种匹配方法,只要其中之一符合即可
坑点:
“” == “”
“” == “a*b*”
‘*’不一定要匹配所有相同的字符 (“aab” == “a*ab”)
代码:
bool isEqual(char a, char b) {
return a == b || b == '.';
}
// 递归求解,每次只判断一个字符
bool recur(string &s, string &p, int sbegin, int pbegin) {
// 基础情况:s为空
if (s.size() - sbegin == 0) {
if (p.size() - pbegin == 0) return true;
else if (p.size() - pbegin >= 2 && p[pbegin + 1] == '*')
return recur(s, p, sbegin, pbegin + 2);
return false;
}
// 基础情况:p为空,s不为空
if (p.size() - pbegin == 0) return false;
// 递归情况
// 情况1:遇到星号 (此处可用递归)
if (pbegin + 1 < p.size() && p[pbegin + 1] == '*') {
// 如果之后有其中之一完全匹配,即完全匹配
int i;
// 匹配1-n个相同字符
for (i = sbegin; i < s.size() && isEqual(s[i], p[pbegin]); i++)
if (recur(s, p, i, pbegin + 2)) return true;
// 匹配所有相同字符,或者字符根本不相同
return recur(s, p, i, pbegin + 2);
}
// 情况2:一般字符匹配
if (isEqual(s[sbegin], p[pbegin]))
return recur(s, p, sbegin + 1, pbegin + 1);
return false;
}
bool isMatch(string s, string p) {
return recur(s, p, 0, 0);
}