leetcode10 Regular Expression Matching @python

来源:互联网 发布:淘宝上退款多久能到账 编辑:程序博客网 时间:2024/06/11 20:45

leetcode里一道hard难度的题(第10题),

题主已经栽死在里面,借鉴了别人优秀的思想用python实现了,经典的东西要保留。

感谢@Vosky,出处链接http://blog.csdn.net/hk2291976/article/details/51165010


题目描述:

Implement regular expression matching with support for ‘.’ and ‘*’.

‘.’ Matches any single character. 
‘*’ Matches zero or more of the preceding element.

The matching should cover the entire input string (not partial).

The function prototype should be: 
bool isMatch(const char *s, const char *p)

Some examples: 
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

这题最难的就是对‘*’的判断,情况多到超出你我想象,

但是有一点,”*”不会单独出现,它一定是和前面一个字母或”.”配成一对。看成一对后”X*”,它的性质就是:要不匹配0个,要不匹配连续的“X”。

题目的关键就是如何把这一对放到适合的位置。

考虑一个特殊的问题: 
情况1: 
“aaaaaaaaaaaaaaaa” 
“a*aa*”

情况2: 
“aaaaaaaaaaaaaaaa” 
“a*ab*”

在不知道后面的情况的时候,我如何匹配a*?

  • 最长匹配 
    显然不合适,这样后面的a就无法匹配上了

  • 匹配到和后面长度一样的位置,比如情况1,就是留3个a不匹配,让后面3个字母尝试去匹配。 
    这样看似合适,但是遇到情况2就不行了。

  • 回溯,每种”*”的情况,看哪种情况能成功,如果其中出现了问题,马上回溯,换下一种情况

下面题主考虑两种方法。(DP太难,题主已弃)


法一:回溯法(暴力法):考虑所有结果

如果“*”不好判断,那我大不了就来个暴力的算法,把“*”的所有可能性都测试一遍看是否有满足的,用两个指针i,j来表明当前s和p的字符。

我们采用从后往前匹配,为什么这么匹配,因为如果我们从前往后匹配,每个字符我们都得判断是否后面跟着“*”,而且还要考虑越界的问题。但是从后往前没这个问题,一旦遇到“*”,前面必然有个字符。

 

如果j遇到 ”*”,我们判断s[i] 和p[j-1]是否相同,

如果相同我们可以先尝试匹配掉s的这个字符,i–,然后看之后能不能满足条件,满足条件,太棒了!我们就结束了,如果中间出现了一个不满足的情况,马上回溯到不匹配这个字符的状态。

不管相同不相同,都不匹配s的这个字符,j-=2 (跳过“*”前面的字符)

还是递归哦

if ((i > -1) and (p[j-1] == '.' or p[j-1] == s[i])):    if (self.myMatch(s,i-1,p,j)):      return Trueelse:   return self.myMatch(s,i,p,j-2)

如果j遇到的不是“*”,那么我们就直接看s[i]和p[j]是否相等,不相等就说明错了,返回。

if (p[j] == '.' or p[j] == s[i]):    return self.myMatch(s,i-1,p,j-1)

再考虑退出的情况

如果j已经<0了说明p已经匹配完了,这时候,如果s匹配完了,说明正确,如果s没匹配完,说明错误。

如果i已经<0了说明s已经匹配完,这时候,s可以没匹配完,只要它还有”*”存在,我们继续执行代码。

class Solution(object):    def isMatch(self, s, p):        return self.myMatch(s,len(s)-1,p,len(p)-1)    def myMatch(self, s, i, p, j):        if j == -1:            if i == -1:                return True            else:                return False        if (p[j] == '*'):            if ((i > -1) and (p[j-1] == '.' or p[j-1] == s[i])):                if (self.myMatch(s,i-1,p,j)):                    return True            else:                return self.myMatch(s,i,p,j-2)        if (p[j] == '.' or p[j] == s[i]):            return self.myMatch(s,i-1,p,j-1)        return False

二、用python正则库re直接解决

import reclass Solution(object):    def isMatch(self,s,p):        return re.match(p,s) != None


原创粉丝点击