动态规划-正则表达式匹配

 

10 正则表达式匹配 https://leetcode-cn.com/problems/regular-expression-matching/

给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。
'.' 匹配任意 单个字符
'*' 匹配 零个或多个前面的那一个元素
所谓匹配,是要涵盖整个字符串 s的,而不是部分字符串。
说明:
s 可能为空,且只包含从 a-z 的小写字母。
p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *

示例 1:
输入:
s = "aa"
p = "a"
输出: false
解释: "a" 无法匹配 "aa" 整个字符串。
示例 2:
输入:
s = "aa"
p = "a*"
输出: true
解释: 因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 'a'。因此,字符串 "aa" 可被视为 'a' 重复了一次。
示例 3:
输入:
s = "ab"
p = ".*"
输出: true
解释: ".*" 表示可匹配零个或多个('*')任意字符('.')。
示例 4:
输入:
s = "aab"
p = "c*a*b"
输出: true
解释: 因为 '*' 表示零个或多个,这里 'c' 为 0 个, 'a' 被重复一次。因此可以匹配字符串 "aab"。
示例 5:
输入:
s = "mississippi"
p = "mis*is*p*."
输出: false

 

思路:

dp[i][j] 表示 s 的前 i 个是否能被 p 的前 j个匹配
p[j] == s[i] or p[j]=='.' :  dp[i][j] = dp[i-1][j-1]
然后从 p[j] 可能的情况来考虑,让 p[j]=各种能等于的东西。

p[j] ==" * ":
1. p[j-1] != s[i] : dp[i][j] = dp[i][j-2]

2. p[j-1] == s[i] or p[j-1] == ".":  dp[r][c] = dp[r - 1][c] or dp[r][c - 2]

 

class Solution:
    def isMatch(self, s: str, p: str) -> bool:

        if not p: return not s

        nrow = len(s) + 1
        ncol = len(p) + 1
        # dp 第一行、第一列 没有意义,只是作为递归的初始
        dp = [[False for c in range(ncol)] for r in range(nrow)]

        dp[0][0] = True
        # 在 dp[r][c] 矩阵中, 一定要保证初始的 dp[0][0]=T, 以进行后续的递归,
        # 而 1,3... = *时,此时的 dp[0][c-2] == dp[0][0] = T
        for c in range(1, ncol-1):
            if p[c] == '*':
                dp[0][c+1] = dp[0][c - 1]
            

        for r in range(1, nrow):
            i = r - 1
            for c in range(1, ncol):
                j = c - 1
                # 只是 计算满足情况的条件
                if s[i] == p[j] or p[j] == '.':
                    dp[r][c] = dp[r - 1][c - 1] # 同时推进
                    
                elif p[j] == '*':
                    if p[j - 1] == s[i] or p[j - 1] == '.' :
                        # 保证 p的前一位 = s, 此时可以是2种情况,  
                        #  *=1  -- dp[r-1][c],   *=0 -- dp[r][c-2]
                        dp[r][c] = dp[r - 1][c] or dp[r][c - 2]
                    else:
                        #  p 的前一位 != s,  *=0  , 取  dp[r][c-2] 位值
                        dp[r][c] = dp[r][c - 2]

        return dp[- 1][- 1]




if __name__ == "__main__":
    s = "aab"
    p = "c*a*b"
    ss = Solution()
    r = ss.isMatch(s,p)
    print(r)

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章