LintCode 正则表达式匹配

实现支持’.’和’*’的正则表达式匹配。

‘.’匹配任意一个字母。

‘*’匹配零个或者多个前面的元素。

匹配应该覆盖整个输入字符串,而不仅仅是一部分。

需要实现的函数是:bool isMatch(const char *s, const char *p)

样例
isMatch(“aa”,”a”) → false

isMatch(“aa”,”aa”) → true

isMatch(“aaa”,”aa”) → false

isMatch(“aa”, “a*”) → true

isMatch(“aa”, “.*”) → true

isMatch(“ab”, “.*”) → true

isMatch(“aab”, “c*a*b”) → true

通配符匹配类似,遇到*的时候处理不同,这个如何处理搞了我好久。。。。很难受

同样是动态规划。
直接来看代码吧

class Solution:
    """
    @param: s: A string 
    @param: p: A string includes "?" and "*"
    @return: is Match?
    """
    def isMatch(self, s, p):
        # write your code here
        m=len(s)
        n=len(p)
        dp=[[False]*(n+1) for x in range(m+1)]
        dp[0][0]=True
        for i in range(1,n+1):
            #此处计算dp[0][j].当p中第j个字符是*时,看看把*去掉,或者把*之前的字符一块去掉,是否匹配。
            if p[i-1]=='*': 
                if dp[0][i-1]==True or dp[0][i-2]==True:
                    dp[0][i]=True
        for i in range(1,m+1):
            for j in range(1,n+1):
                if s[i-1]==p[j-1] or p[j-1]=='.':#相等或p中字符是‘.’,没什么说的。
                    dp[i][j]=dp[i-1][j-1]
                elif p[j-1]=='*':  # 如果p中字符是*:看下面文字吧
                    pre=p[j-2]
                    if pre!=s[i-1] and pre!='.':
                        dp[i][j]=dp[i][j-2]
                    else:
                        if dp[i][j-1]==True or dp[i][j-2]==True:#判断pre出现1次或0次能否匹配
                            dp[i][j]=True
                        else:
                            for k in range(1,i):
                                if dp[i-k][j-2]==True or dp[i-k][j-1]==True:
                                    dp[i][j]=True
                                    break
                                elif s[i-k]==s[i-k-1]:
                                    continue
                                else:
                                    break
        #print dp
        return dp[m][n]

如果p中字符是星号的话,用pre记录星号前面的字符。
1. 当pre不等于s中当前字符而且,pre也不是 点 的时候,那么无论这个pre重复1次还是几次,都匹配不上,只能是0次有可能匹配,所以dp[i][j]=dp[i][j-2]。
2. pre等于s中当前字符或者pre是 点 。那么首先判断 这个pre出现1次或者出现0次时是否能匹配。不能匹配的话,继续。pre出现2次以上,那么这就相当于在p串不变的情况下,从s串中的尾部连续删掉x个pre(注意这些删掉的字符必须相同,不相同的时候,就停止)。

这个 星号处理 有可能有重复的判断,但是应该是很少一部分。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值