正则表达式匹配(略难)

时间:2022-12-10 05:34:25

题目描述
请实现一个函数用来匹配包括’.’和’‘的正则表达式。模式中的字符’.’表示任意一个字符,而’‘表示它前面的字符可以出现任意次(包含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] == '.'){
                return matchCode(str,s,pattern,p+2) || matchCode(str,s+1,pattern,p+2) || matchCode(str,s+1,pattern,p);
            }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);
    }
}

注意了:必须先判断“ * ”的情况,然后再判断“ . ”的情况。==》案例:“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);        
    }
}