剑指offer——正则表达式匹配C++

在这里插入图片描述
难点有2
1:理清思路很难。2:"“的匹配有很多情况不知道到底是匹配几个很难。
这里我们用的是递归求解。分情况:先看pat的下一个是否为” * “,如果是,那么又有两种情况,当前位是否匹配,如果当前位匹配(可以用两个字符串当前字符相等或者pat当前字符为”.“来判断),那么要看接下来这个”
“到底要匹配多少次了。第一种情况aa和aaa,匹配0次;第二种情况aa和aa,匹配1次;第三种情况aaab和a*b匹配多次。所以我们递归判断每一种情况,只要有一种为true,那么就是true,用||运算符。匹配0次是str不动,pat后移两位…以此类推即可。
如果不能匹配,那么 一定是匹配0次的,所以递归判断str不变,pat后移两位。
如果下一位不为"
”,如果匹配(也是用两个式子判断)就均移一位。如果不匹配,就是false。
细节需要很注意,递归边界以及一开始的边界条件char * 是否为空用==’\0’来判断,递归边界是如果两者同时走到底就是true,走到是当前位等于长度,而不是长度-1。如果pat走到底了,str没到底,就是false。
还有一个细节是每次都要判断是否会越界!这很重要,要放在&&的前面,后面才是取字符

class Solution {
public:
    bool helpMatch(string str,int strIndex,string pattern, int patIndex){
        //递归函数,递归边界和递归式
        //这里的递归式分情况讨论
        //递归边界就是一边到底了,一边没到;或者两边都到了就是true
        if(str.length() == strIndex && pattern.length() == patIndex){
            return true;
        }
        //如果pat到底了,str没到底,就是false,因为pat一般来说走的比较快
        if(pattern.length() == patIndex && str.length() != strIndex){
            return false;
        }
        //分情况,主要是看下一个是否为'*',先确保长度不会超,用&&
        if(patIndex < pattern.length()-1 && pattern[patIndex+1] == '*'){
            //又要分情况,如果当前位是匹配的,分3种情况
            if(str[strIndex] == pattern[patIndex] || (strIndex != str.length() && pattern[patIndex] == '.')){
                //第一种aa和a*aa,匹配0次,所以pat往后移两位
                //第二种ab和a*b,匹配1次,所以str往后1位,pat往后2位
                //第三种aab和a*b,匹配多次,但是你不知道具体要匹配几次,
                //就一步一步往后推,str一位一位往后即可。递归要做的就是目前要做的事,后面的事交给后面的递归
                //pat不变
                return (helpMatch(str,strIndex,pattern,patIndex+2) ||
                       helpMatch(str,strIndex+1,pattern,patIndex+2)||
                       helpMatch(str,strIndex+1,pattern,patIndex));
            }
            else{
                //如果是不匹配的,那么只能匹配0次,str不动,pat后2位
                return helpMatch(str,strIndex,pattern,patIndex+2);
            }
        }
        //下一位不是*,正常匹配,如果不匹配,直接false
        if(patIndex < pattern.length() && pattern[patIndex+1] != '*'){
            if(str[strIndex] == pattern[patIndex] || (pattern[patIndex]=='.' && strIndex != str.length())){
                return helpMatch(str,strIndex+1,pattern,patIndex+1);
            }
        }
        return false;
    }
    
    bool match(char* str, char* pattern)
    {
        //主要是要分清楚所有情况
        //str是字符串,pattern是模式串
        //先考虑只有".",没有"*"的情况,如果当前字符相等或者pattern[j]=='.'都算匹配上了
        //继续考虑"*",如果在匹配的情况下
        /*int i = 0, j = 0;
        //先强转
        string a = str, b = pattern;
        while(i < a.length()&& j < b.length()){
            if(a[i] == b[j] || b[j] == '.'){
                //匹配成功
                if(j < b.length()-1 && b[j+1] == '*'){
                    //匹配0次或者匹配多次
                }
                else{
                    i++;
                    j++;
                }
            }
            else{
                if(j < b.length() - 1 && b[j+1] == '*'){
                    //只能匹配0次
                }
                else{
                    return false;
                }
            }
        }
        return i == j;*/
        if(*str == '\0' && *pattern == '\0') return true;
        if(*pattern == '\0') return false;
        string a = str, b = pattern;
        int strIndex = 0, patIndex = 0;
        return helpMatch(a,strIndex,b,patIndex);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值