LeetCode.10.正则表达式匹配

≡放荡痞女 提交于 2020-02-27 01:03:07

这个比较困难,我参考了网上的代码: https://leetcode-cn.com/problems/regular-expression-matching/solution/di-gui-dong-tai-gui-hua-zhu-xing-jie-shi-python3-b/

思路: 动态规划, 沿着匹配串和字符串构成矩阵的对角线传递状态
1. 状态矩阵的首行与首列对应于空字符与空匹配符
2. 对角线意味着匹配串是否匹配对应的字符串

具体代码以下:

'''
p.charAt(j) == s.charAt(i) : dp[i][j] = dp[i-1][j-1]
If p.charAt(j) == '.' : dp[i][j] = dp[i-1][j-1];
If p.charAt(j) == '*': here are two sub conditions:
//in this case, a* only counts as empty, otherwise is not match
- if p.charAt(j-1) != s.charAt(i) : dp[i][j] = dp[i][j-2]
- if p.charAt(j-1) == s.charAt(i) or p.charAt(i-1) == '.':
    dp[i][j] = dp[i-1][j]    //in this case, a* counts as multiple a
    dp[i][j] = dp[i][j-1]   // in this case, a* counts as single a
    dp[i][j] = dp[i][j-2]   // in this case, a* counts as empty

'''
def isMatch(s, p):
    ls=len(s)             #length of s
    lp=len(p)             #length of p
    #定义dp空间
    dp=[[False]*(lp+1) for _ in range(ls+1)]
    dp[0][0]=True
    #初始化首行
    for i in range(lp):
        if p[i]=='*' and dp[0][i-1]:
            dp[0][i+1]=True
    #更新状态dp
    for i in range(1,ls+1):        #dp指针,从1开始  
        for j in range(1,lp+1):    #0地址已经初始化为True
            m=i-1                  #s指针,从0开始
            n=j-1                  #p指针
            if s[m]==p[n]:                     #如果字符匹配
                dp[i][j]=dp[i-1][j-1]          #获取前一dp状态
            elif p[n]=='.':                    #.肯定能匹配字符
                dp[i][j]=dp[i-1][j-1]          #获取前一dp状态
            elif p[n]=='*':        #处理字符为*,*表示n-1的延续
                if s[m]==p[n-1] or p[n-1]=='.':    #
                    dp[i][j]=dp[i-1][j] or dp[i][j-1] or dp[i][j-2]
                elif s[m]!=p[n-1]:              #字符不等于*的前位字符 
                    dp[i][j]=dp[i][j-2]        #获取前二位dp状态

    return dp[ls][lp]
    

s=['ab','aaabc','ab']
p=['abc*','a*bc','.*']
print(isMatch(s[2],p[2]))

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!