動態規劃-正則表達式匹配

 

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)

 

 

 

 

 

 

 

 

 

 

 

 

 

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