53 正则表达式匹配(略难)

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

后来,我自己写了一遍,发现是有一些逻辑的。
(1)以两数组指针的位置为判断基准,当两指针都指向数组最后一位的下一位,说明匹配(当最后一位匹配的话,肯定要往后移动一位);
(2)若str尚未到最后一位,但模式串中到了最后一位,此时肯定不匹配;
(3)若str到了最后一位,模式串尚未到最后,此时,模式串只有p+1指针位置的字符判断机会,如果是“*”的话,它可以表示0个,那么此时匹配;否则不匹配;
(4)然后判断当模式串的下一位是“ * ”的时候,如果str的当前位和模式串的当前位字符相等,那么有三种情况:前数字出现的次数分别是0,1,多次;如果不相等,那么只有当“ ”出现次数为0的时候,可能为匹配(只是可能),接着匹配模式串的下两位;否则不匹配;
(5)当当前位相等,或者模式串的字符为‘ . ’的时候,接着匹配下一位;
注意:第(4)步是预判断下一位,因此,要早于第五步。

public class Solution {       
    public boolean matchCode(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(s == str.length && p < pattern.length){
            if(p+1 == pattern.length-1 && pattern[p+1]=='*'){
                return true;
            }
            return false;
        }
        if(p+1< pattern.length && pattern[p+1] == '*'){
            if(str[s] == pattern[p] || pattern[p] == '.'){
            //匹配0位,串不动,模式串直接后移2位;
                return matchCode(str,s,pattern,p+2) || matchCode(str,s+1,pattern,p+2) //匹配1位,串后移1为,模式串后移2位
                || matchCode(str,s+1,pattern,p);//匹配1位以上,串后移一位,模式串不变
            }else if(str[s] != pattern[p]){
                return matchCode(str,s,pattern,p+2); 
            }
            return false;
        }
        if(s< str.length && p<pattern.length && (str[s] == pattern[p] || pattern[p] == '.')){            
            return matchCode(str,s+1,pattern,p+1);
        }                       
        return false;
    }
    public boolean match(char[] str, char[] pattern)
    {
        if(str == null || pattern == null)
            return false;
        return matchCode(str,0,pattern,0);
    }
}

当模式串第二个字符为‘**’的时候:
(1)如果模式中的第一个字符和字符串中的第一个字符不匹配,字符串不变,模式串后移两位,相当于※匹配了0位
(2)如果模式中的第一个字符和字符串中的第一个字符相匹配时,则字符串向后移动一个字符,串后移1,那么模式串可以有两种选择:
(a)模式串后移两个字符
(b)模式串不变
(c)也可以和(1)一样

注意了:必须先判断“ * ”的情况,然后再判断“ . ”的情况。==》案例:“aa”,“a*”
因为“ * ”可能代表着0个,这样的话,当前位可能就不存在了,比较“.”没有意义。
上述案例,如果先比较“ . ”的话,第一轮都向前移动1,第二轮直接比较‘a’ 和 ‘’了,这样的话,‘’前面的位置过去了,就没有比较的必要了。因为‘*’可能是0,1,2,3。。。的多样性不能表示出来。

public class Solution {
    public boolean matchCore(char[] str,int strIndex,char[] pattern,int patternIndex){
        if((strIndex == str.length) && (patternIndex == pattern.length))
            return true;
        if((strIndex != str.length) && (patternIndex == pattern.length))
            return false;

        if(strIndex==str.length && patternIndex != pattern.length) {
            while(patternIndex != pattern.length){
                if(pattern[patternIndex]!='*' && (patternIndex+1>=pattern.length||pattern[patternIndex+1]!='*')){
                    return false;
                }
                patternIndex++;
            }
            return true;
        }

        if((patternIndex+1 < pattern.length) && (pattern[patternIndex+1] == '*')){
            if((str[strIndex] == pattern[patternIndex]) || (pattern[patternIndex] == '.')){
                return matchCore(str,strIndex + 1,pattern,patternIndex + 2)
                    || matchCore(str,strIndex + 1,pattern,patternIndex)
                    || matchCore(str,strIndex,pattern,patternIndex + 2);
            }else{
                return matchCore(str,strIndex,pattern,patternIndex + 2);
            }
        }
         if((str[strIndex] == pattern[patternIndex]) || (pattern[patternIndex] == '.')){
            return matchCore(str,strIndex + 1,pattern,patternIndex + 1);
        }
        return false;           
    }
    public boolean match(char[] str, char[] pattern)
    {
        if(str == null || pattern == null)
            return false;      

        int strIndex = 0;
        int patternIndex = 0;
        return matchCore(str,strIndex,pattern,patternIndex);        
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值