LeetCode10--Regular Expression Matching

这一题从前往后事实上是很难找到办法解决的,当正面无法解决问题时我们不妨换一个角度思考,从后往前匹配

先来个大概的思路:当当前位置字符一样,显然最后是否能匹配取决于前面位置能否能匹配,所以要考虑前面位置是否匹配,而前面位置是否匹配,取决于那个位置值是否匹配(相同?. 等)和那个位置前面的值是否匹配。不难看出,这有点像反递推。

接下来我们来考虑细的思路 :
当往前推超出了界限,我们需要特判。
当一个结束另一个未结束也需要特判。
若两个都未结束:
若两个相等,取决于当前位置的前一个位置是否能匹配
若是 ‘.’ ,则默认这个位置匹配了,跟上面是一样的行为
若是 ‘*’ ,那么这个可以匹配 星号 前面字符0次,1次或者多次。只要有一种情况匹配上了都认为可以匹配上。匹配0次时是否能匹配,则取决于模式串前两位和待匹配串当前位是否能匹配。匹配1次,则情况变成了判断模式串前一位(星号以前的那个字符)是否能与待匹配串的当前位匹配。匹配一次以上也是类似的情况,直接继续往前递推即可。

class Solution {
public:
    bool IsAlpha(char c)
    {
        if(c >= 'a' && c <='z')
            return true;
        return false;
    }
    int AllStar(string &p,int k)
    {
        int temp = 0;
        for(;k < p.length();++k)
                if(p[k] != '*')
                    return 1;
        return temp;
    }
    bool Match(string &s,string &p,int i1,int i2)
    {
        if(i1 < 0)
        {
            if(i2 < 0)
                return true;
            if(p[i2] != '*')
                return false;
            //如果i2还不等于0,那么判断前面是不是都是  字符*字符*...
            return Match(s,p,i1,i2-2);//是*,则跳过它控制的字符继续判断
        }
        else if(i2 < 0)//i2结束了,但是l1还存在字符未匹配
            return false;
        //从后往前匹配,若是字母
        if(IsAlpha(p[i2]))
        {
            if(s[i1]!=p[i2])
                return false;
            else
                return Match(s,p,i1-1,i2-1);
        }
        else if(p[i2] == '.')
            return Match(s,p,i1-1,i2-1);
        else if(p[i2] == '*')//匹配前面的字符一次或者多次
        {
            //可匹配前面字符0次,或者1次,或者多次
            // Match(s,p,i1,i2-2)//匹配0次
            // Match(s,p,i1,i2-1)//匹配1次
            // Match(s,p,i1-1,i2)//匹配多次
            //若*号前面没有字符
            if(i2-1 < 0)
                return false;
            //匹配0次则无需管字符是不是对的,若匹配多次则需要判断字符是否正确
            //字符相同或者是.都算
            return Match(s,p,i1,i2-2)||((s[i1] == p[i2-1] ||  p[i2-1] == '.') && Match(s,p,i1,i2-1))||((s[i1] == p[i2-1] ||  p[i2-1] == '.')&&Match(s,p,i1-1,i2));
           }
        return true;
    }
    bool isMatch(string s, string p) {
        //.匹配任意字符
        //*匹配前者0次或者多次
        //s只含小写字母
        //p只含小写字母和.*
        return Match(s,p,s.length()-1,p.length()-1);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值