10. 正则表达式匹配

52 篇文章 0 订阅
44 篇文章 0 订阅

在这里插入图片描述
在这里插入图片描述
牛客的递归超时了,要用dp。这里也是二维dp,二维dp=填表。
字符串好多都是用二维dp,这里是记录两个字符串的位置,回文子串是记录首尾下标。

class Solution {
public:
    /*bool matchCore(string s, string p, int sIndex,int pIndex){
        //如果两者同时走到结尾就是true
        if(s.length() == sIndex && p.length() == pIndex) return true;
        //如果p先走到尾了而s还没就是false
        if(p.length() == pIndex && s.length() != sIndex) return false;
        
        if(pIndex+1 < p.length() && p[pIndex+1] == '*'){
            //如果下一位是*,再次分情况,判断当前位是否相等
            if(s[sIndex] == p[pIndex] || (sIndex != s.length()&&p[pIndex] == '.')){
                //aaa,a*,匹配n次;a,a*匹配一次;aa,a*aa匹配0次
                return (matchCore(s,p,sIndex+1,pIndex) || 
                        matchCore(s,p,sIndex+1,pIndex+2)||
                        matchCore(s,p,sIndex,pIndex+2));
            }
            else{
                //如果当前位不相等,那么只能匹配0次
                return matchCore(s,p,sIndex,pIndex+2);
            }
        }
        if(pIndex < p.length() && p[pIndex+1] != '*'){
            if(s[sIndex] == p[pIndex] || (sIndex != s.length() && p[pIndex] == '.')){
                return matchCore(s,p,sIndex+1,pIndex+1);
            }
        }
        return false;
    }*/
    bool isMatch(string s, string p) {
        //递归判断
        //在下一位可以取到的情况下判断下一位是否是*
        //如果不是*,就判断当前位是否相等
        //如果是,就找出*匹配了当前的几位,n位or0位 
        //return matchCore(s,p,sIndex,pIndex);

        //dpcode,dp[i][j]存的是s的前i位能否被p的前j位成功匹配
        int sLen = s.length(), pLen = p.length();
        vector<vector<bool>> dp(sLen+1,vector<bool>(pLen+1,false));

        //初始化
        dp[0][0] = true;
        //dp[i][j],当i等于0时,a*b*这种字符串还是可以匹配的
        for(int i = 1; i <= pLen; ++i){
            if(i >= 2 && p[i-1] == '*' && dp[0][i-2]) dp[0][i] = true;
        }
        for(int i = 1; i <= sLen; ++i){
            for(int j = 1; j <= pLen; ++j){
                //如果当前字符相等,那么只要前面的可以成功匹配,它也是可以成功地
                if(s[i-1] == p[j-1] || p[j-1] == '.'){
                    //dp[i][j]记录的是s[i-1]之前以及自身和p[j-1]之前以及自身能否匹配
                    dp[i][j] = dp[i-1][j-1];
                }
                //如果不相等,就判断当前位是否是*
                else if(p[j-1] == '*' && j>=2){
                    //判断p[j-1]的前一位能否和s[i-1]匹配,如果不能,就相等于当前*匹配0次
                    //dp[i][j]就要根据dp[i][j-2]来判断
                    if(p[j-2] != s[i-1] && p[j-2]!='.'){
                        dp[i][j] = dp[i][j-2];
                    }
                    //如果前一位匹配上了,那么也有三种情况
                    //匹配0次,匹配1次,匹配n次,只要有一种情况成功匹配就行
                    else{
                        dp[i][j] = dp[i][j-2] || dp[i][j-1] || dp[i-1][j];
                    }
                }
                else dp[i][j] = false;
            }
        }
        return dp[sLen][pLen];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值