标签:匹配 string 递归 正则表达式 int return LeetCode size
给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配
- '.' 匹配任意单个字符
- '*' 匹配零个或多个前面的那一个元素
1. 暴力递归
由于*匹配零个或多个前面元素,所以遍历是有方向的,从后往前递归判断,使问题规模缩小
class Solution {
public:
bool isMatch(string s, string p) {
//只要有一种匹配成功就返回真
int m = s.size();int n = p.size();
return Match(s,p,m-1,n-1);//从后往前
}
bool Match(string &s,string &p,int i,int j){
//边界条件
if(i<0&&j<0) return true;//已经匹配完
else if(j<0) return false;//模板串遍历完,匹配失败
else if(i<0){//模板串有*可以自己消除
if(p[j]=='*') return Match(s,p,i,j-2);
return false;
}
if(s[i]==p[j]||p[j]=='.') return Match(s,p,i-1,j-1);//匹配一次
if(p[j]=='*'){
if(j==0) return false;//前面没数了
if(s[i]==p[j-1]||p[j-1]=='.')//跟前面的数匹配的话
{
//匹配零次前面字符
bool flag1 = Match(s,p,i,j-2);
//匹配一次
bool flag2 = Match(s,p,i-1,j-1);
//匹配多次
bool flag3 = Match(s,p,i-1,j);
return flag1|flag2|flag3;
}
else return Match(s,p,i,j-2);//不匹配的话跳过
}
return false;
}
};
2. 动态规划
显然方法一中有很多重复递归,用而二维数组将其记录,减少重复递归
这里直接从前往后动态规划
class Solution {
public:
bool isMatch(string s, string p) {
int m = s.size();
int n = p.size();
auto matches = [&](int i, int j) {//匿名函数
if (i == 0)//匹配失败
return false;
if (p[j - 1] == '.')
return true;//可以匹配成功
return s[i - 1] == p[j - 1];//相等匹配成功,不等失败
};
vector<vector<int>> f(m + 1, vector<int>(n + 1));//多出来的行列存储边界,默认为0
f[0][0] = true;//边界条件
for (int i = 0; i <= m; ++i) {//从左往右
for (int j = 1; j <= n; ++j) {//从上往下,从1开始,因为第一列为边界0
if (p[j - 1] == '*') {//第j个字符为*,这里其实默认了模板串第一个不会为*
f[i][j] |= f[i][j - 2];//选择跳过,匹配零次
if (matches(i, j - 1)) //不跳过的情况,前一个字符可以进行匹配
f[i][j] |= f[i - 1][j];//匹配多次
}
else if (matches(i, j)) //当前可匹配
f[i][j] |= f[i - 1][j - 1];//匹配一次
}
}
return f[m][n];//返回主串前m个字符和模板串前n个字符匹配情况
}
};
标签:匹配,string,递归,正则表达式,int,return,LeetCode,size 来源: https://www.cnblogs.com/929code/p/16387534.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。