正则表达式匹配
给定一个字符串 (s
) 和一个字符模式 (p
)。实现支持 '.'
和 '*'
的正则表达式匹配。
'.' 匹配任意单个字符。 '*' 匹配零个或多个前面的元素。
匹配应该覆盖整个字符串 (s
) ,而不是部分字符串。
说明:
s
可能为空,且只包含从a-z
的小写字母。p
可能为空,且只包含从a-z
的小写字母,以及字符.
和*
。
示例 1:
输入: s = "aa" p = "a" 输出: false 解释: "a" 无法匹配 "aa" 整个字符串。
示例 2:
输入: s = "aa" p = "a*" 输出: true 解释: '*' 代表可匹配零个或多个前面的元素, 即可以匹配 'a' 。因此, 重复 'a' 一次, 字符串可变为 "aa"。
示例 3:
输入: s = "ab" p = ".*" 输出: true 解释: ".*" 表示可匹配零个或多个('*')任意字符('.')。
示例 4:
输入: s = "aab" p = "c*a*b" 输出: true 解释: 'c' 可以不被重复, 'a' 可以被重复一次。因此可以匹配字符串 "aab"。
示例 5:
输入: s = "mississippi" p = "mis*is*p*." 输出: false
思路:
对p字符串进行分步,单步只使用一位或者两位,分成如下四种情况,返回匹配个数
单步一位:
- 当前字符的后一位不是' * ',且当前字符是非' . '字符,与s字符串所扫描到的当前字符是否匹配
- 当前字符的后一位不是' * ',且当前字符是' . '字符,与s字符串所扫描到的当前字符必然匹配
int isSimpleMatch(string& s, int s_i, string& p, int p_i)
{
if (s_i >= s.length())
return -1;
// 情况1
if (p[p_i] != '.')
return s[s_i] == p[p_i] ? 1 : -1;
// 情况2
else
return 1;
}
单步两位:
- 当前字符为非' . '字符,且后一位为' * ',与s字符串所扫描到的当前字符以及后续相同字符匹配
- 当前字符为' . '字符,且后一位为' * ',与s字符串所扫描到的当前字符以及后续所有字符匹配
int isDoubleMatch(string& s, int s_i, string& p, int p_i)
{
// 情况3
if (p[p_i] != '.')
{
int num = 0;
for (int i = s_i; i < s.length(); ++i)
{
if (s[i] == p[p_i])
num++;
else
break;
}
return num;
}
// 情况4:即为".*"
else
return s.length() - s_i;
}
对于整体而言,p字符中' * '为非贪婪匹配,所以每次扫描到' * ',需要记录当前扫描状态,以便后续匹配不成功,可以回溯
主函数:
bool isMatch(string s, string p) {
int s_i = 0;
int p_i = 0;
vector<int> backNums;
vector<int> backP_is;
vector<int> backS_is;
while (p_i < p.length())
{
int num = 0;
if (p_i + 1 < p.length() && p[p_i + 1] == '*')
{
num = isDoubleMatch(s, s_i, p, p_i);
p_i = p_i + 2;
if (num > 0)
{
backNums.push_back(num);
backP_is.push_back(p_i);
backS_is.push_back(s_i);
}
}
else
{
num = isSimpleMatch(s, s_i, p, p_i);
p_i++;
}
if (num < 0)
{
if (backNums.empty())
return false;
if (backNums.empty())
return false;
backNums[backNums.size() - 1]--;
p_i = backP_is[backNums.size() - 1];
s_i = backS_is[backNums.size() - 1] + backNums[backNums.size() - 1];
if (backNums[backNums.size() - 1] == 0)
{
backNums.pop_back();
backP_is.pop_back();
backS_is.pop_back();
}
}
else
s_i = s_i + num;
}
return s_i >= s.length();
}
结果: