剑指offer:正则表达式匹配Java实现以及错误反思

题目描述

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

代码思路

当模式中的第二个字符是星号时:
如果字符串第一个字符跟模式第一个字符不匹配,则模式后移2个字符,继续匹配(相当于星号前面的)。如果字符串第一个星号字符跟模式第一个字符匹配,可以有3种匹配方式:
1.模式后移2字符,相当于x星号被忽略;
2.字符串后移1字符,模式后移2字符,相当于x星号匹配一位;
3.字符串后移1字符,模式不变,即继续匹配字符下一位,相当于x星号匹配多位;
当模式中的第二个字符不是星号时:
如果字符串第一个字符和模式中的第一个字符相匹配,那么字符串和模式都后移一个字符,然后匹配剩余的部分。
如果字符串第一个字符和模式中的第一个字符相不匹配,直接返回False。

错误代码反思

由于写代码之前没有认真思考 str和pattern 的关系,写出了如下代码

public class Solution {
    public boolean match(char[] str, char[] pattern)
    {
        if (str == null || pattern == null)
            return false;
        return matchcore(str, pattern,0,0);
    }
    
    private boolean matchcore(char[] str, char[] pattern, int s, int p){
        if(str.length == s && pattern.length == p)
            return true;
        if (s < str.length && p == pattern.length)
            return false;
        //错误1:
        if(s == str.length && p < pattern.length)
            return false;
        
        if(pattern[p+1] == '*'){//错误二
            if(pattern[p]=='.' || pattern[p] == str[s])//错误三
                return matchcore(str, pattern, s+1,p)||
                        matchcore(str, pattern, s+1,p+2)||
                        matchcore(str, pattern, s,p+2);
            else
                return matchcore(str, pattern, s,p+2);
        }
        if(pattern[p]=='.' || pattern[p] == str[s])//错误四
           return matchcore(str, pattern, s+1,p+1);
        return false;
    }
}

错误一:没有考虑特殊情况。当str的指针指向最后一个元素时,如果pattern最后两个元素为.* 那么仍然是匹配成功的情况。
错误二:当变量作为数组下表出现时,没有注意边界的判定。
错误三:因为接下来涉及到s+1作为方法参数,必须确保s+1<=str.length,错误四同理。

修改后的代码

public class Solution {
    public boolean match(char[] str, char[] pattern)
    {
        if (str == null || pattern == null)
            return false;
        return matchcore(str, pattern,0,0);
    }
    
    private boolean matchcore(char[] str, char[] pattern, int s, int p){
        if(str.length == s && pattern.length == p)
            return true;
        if (s < str.length && p == pattern.length)
            return false;

        if(p + 1 < pattern.length && pattern[p+1] == '*'){
            if ((s < str.length && pattern[p] == '.')|| (s < str.length && pattern[p] == str[s]))
                return matchcore(str, pattern, s+1,p)||
                        matchcore(str, pattern, s+1,p+2)||
                        matchcore(str, pattern, s,p+2);
            else
                return matchcore(str, pattern, s,p+2);
        }
        if(s < str.length && (pattern[p]=='.' || pattern[p] == str[s]))
           return matchcore(str, pattern, s+1,p+1);
        return false;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值