牛客网 正则表达式匹配

题目:请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配。

这道题最开始我的分析思路有点偏差,重点在于如何分析这个“*”. 显然当一个一个字符读入的时候,当读到*字符的时候我们是找不到前面那个他能重复的字符的,所以说应该每次读入一个字符,看一下这个字符之后是不是*,如果是*是一种处理办法,不是则是另一种处理办法。代码如下:

class Solution {
public:
    bool match(char* str, char* pattern)
    {
        //这里面只有pattern里面的内容包括.和*
        if(str == nullptr && pattern == nullptr) return false;
        return judge(str, pattern);
    }
    bool judge(char* str, char* pattern){
        if( *str == '\0' && *pattern == '\0') return true;
        if( *str != '\0' && *pattern == '\0') return false;
        
        //上面是边界条件,下面是后续
        if(*(pattern+1)=='*'){
            if(*str == *pattern || (*pattern == '.' && *str!= '\0')){
                
                return judge(str+1, pattern+2) || judge(str+1, pattern) || judge(str, pattern+2);
            }
            else{//比如aa和b*的情况
                return judge(str, pattern+2);
            }
        }
        if(*str == *pattern){//只有可能是两个符号,不可能是.或者*,并且pattern当前的符号的下一个不可能是*了
            return judge(str+1, pattern+1);
        }
        else if(*pattern == '.'){
            if(*str != '\0') return judge(str+1, pattern+1);
            else return false;
        }
        else return false;
        
    }
};

这道题的关键是:如果遇到了下一个字符是*的处理。因为*可以表示的是重复前面那个字符的任意多次,所以通常的思路是:把这个写成一个循环,看看那个匹配就可以了。但是实际上我们用的方法是:
return judge(str+1, pattern+2) || judge(str+1, pattern) || judge(str, pattern+2);

我们知道*可以复制前面那个字符的任意多次,那么当*复制0次的时候,可以认为是当前这个pattern字符和后面的*都失效了,所以对应的是judge(str, pattern+2)。 当这个*重复一次的时候,就认为str的当前位被pattern的*前面的字符抵消掉了,所以是judge(str+1,pattern+2). 那么下一个关键就是judge(str+1,pattern),这个怎么理解呢?这个实际上代表的是*会复制两次或者两次以上所代表的的情况。

这句话怎么理解呢?我们以两个字符串为例:str = "aaaa" pattern = "a*a". 当*代表一个a的时候,实际上我们下一步进行的判断是:str= "aaa", pattern = "a". 当*代表两个a的时候,他其实可以分解看成*首先代表1个a,然后再代表一个a。也就是说,当*代表n个前面的字符的时候,他其实可以看成是复制1次前面的字符,再复制n-1次。但是与单纯的复制1次不同,实际上在这个过程中,str= "aaaa", pattern = "a*a",我们认为在n次复制之后的第一次之后,状态变成了str="aaa", pattern = "a*a",pattern仍不变,因为*可以代表无穷次的复制,单纯的复制1次,理论上pattern的状态机不会改变,而str因为被复制了一位,所以减少了一位。

 

这题挺有意思的,拿出来说一下我的想法,请指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值