面试题19:正则表达式匹配(剑指offer-Java版)

今天在刷剑指offer的时候,遇到一个正则表达式匹配的问题,看题解时觉得题解有点问题,所以就自己写个博客记录一下。

题目描述

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

题解

由于".“可以与任意字符匹配,因此匹配时遇到”.“很容易解决。但是对于”*“字符,就得分情况讨论了:一种是字符串中的字符与模式串中”*“之前的字符不匹配,这种情况下我们可以忽略”*“字符和该字符之前的那个字符,即在模式串上向后移动两位,如"aa"和"ac*a"是匹配的;另一种情况是字符串中的字符与模式串中”*“之前的那个字符匹配,这种情况下又可细分为三种情况:一种是字符串中的字符向后移动一位,模式串不移动,如"aaaac"与"aa*c"是匹配的;另一种字符串的字符移动一位,而模式串中的字符移动两个字符,如"aac"与"aa*c"是匹配的。还有一种是忽略”*"和该字符之前的字符,即字符串中的字符不移动,模式串中的字符移动两位,如"aac"与"aa*ac"也是匹配的。

代码

public class Solution {
    public boolean match(char[] str, char[] pattern)
    {
        return matchStr(str,0,pattern,0);
    }
    public boolean matchStr(char[] str,int i,char[] pattern,int j){
        //两者都为空
        if(i==str.length&&j==pattern.length){
            return true;
        }
        //模式串为空
        else if(j==pattern.length){
            return false;
        }
        boolean next=(j+1<pattern.length&&pattern[j+1]=='*');
        //下一个字符为*时
        if(next){
            //'\*'之前的字符匹配时,上文中提到的三种情况
            if(i<str.length&&(pattern[j]=='.'||str[i]==pattern[j])){
                return matchStr(str,i,pattern,j+2)||matchStr(str,i+1,pattern,j)||matchStr(str,i+1,pattern,j+2);
            }
            //字符不匹配,忽略'\*'及其之前的字符
                return matchStr(str,i,pattern,j+2);
            }
        }
        else {
        //下一个字符不是'\*',就是正常的字符串匹配,如果当前字符匹配,就开始匹配下一个字符,否则就匹配失败
            if(i<str.length&&(pattern[j]=='.'||str[i]==pattern[j])){
                return matchStr(str,i+1,pattern,j+1);
            }
            else{
                return false;
            }
        }
    }
}

你可能感兴趣的:(数据结构与算法)