剑指Offer——正则表达式匹配

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

方法:有两个指针s和p,s指向字符串,p指向模式

1.首先我们分析出现'.'的情况,从题目中可以知道,这个符号可以代表任意一个字符,也就是这两个指针同时后移一位(或者是这两个字符相等)

2.当出现'*'的时候:

   (1)当s和p相等(注意这个相等),p+1是‘*’的时候,会出现三种情况:

                a.模式不变(也就是指针p不变),s向后移动一位。比如abbcd和ab*cf,其中s和p都指向了b。由于b出现了多次,应该不着急移动p,所以此时s+1即可。

                b.忽略这个‘*’,p向后移动两位,s向后移动一位。比如abcd和ab*cf,其中s和p都指向了b。此时应该s+1和p+2

                c.忽略这个'*’,p向后移动两位,s不变。比如"cba","cb*a*a",我也可以认为,p指向的第1个a没出现过,即使你相等。因此此时可以s不动,p+2(也就是直接跳到最后比较)。

 (2)当s和p不相等的时候,p+1是‘*’的情况,相当于这个没出现,p向后移动两位。

由于把真正的相等和'.'标记的相等并成一类,就只用考虑'*'。如果不出现星号,就常规比较,常规比较肯定出现相等或者不等两类。如果出现星号,就考虑两个指针指的是否相等,不等,则p指针直接+2。两个指针相等,则有3种情况并列处理。再在这些判断中,加入对应边界条件,就可以很容易理解并写出代码了。

public class Solution {
    public boolean match(char[] str, char[] pattern)
    {
        if(str==null || pattern==null){
            return false;
        }
       return match(str,0,pattern,0);
    }
    public boolean match(char[] str,int s,char[] pattern,int p){
        if(s==str.length && p==pattern.length){
            return true;
        }
        if(s<str.length && p==pattern.length){
            return false;
        }
        //下一个指针指向的是*
        if(p+1<pattern.length && pattern[p+1]=='*'){
           //出现了*号,并且s和p指的相同
            if((s<str.length && pattern[p]=='.') || (s<str.length && str[s]==pattern[p] )){
                return match(str,s,pattern,p+2) 
                    || match(str,s+1,pattern,p+2) 
                    || match(str,s+1,pattern,p);
            }
            else{
                return match(str,s,pattern,p+2);
            }
        }
        //下一个不是*
        if(s<str.length&& (str[s]==pattern[p] || pattern[p]=='.')){
            return match(str,s+1,pattern,p+1);
        }
        return false;
    }
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值