leetcode題目10之正規表示式匹配
Given an input string (s
) and a pattern (p
), 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).
Note:
s
could be empty and contains only lowercase lettersa-z
.
p
could be empty and contains only lowercase lettersa-z
, and characters like.
or*
用dp(i,j)計算text[i:]與patter[j:]匹不匹配.最終要得到的結果就是dp(0,0)。如果i,j已經計算過,就儲存起來,直接返回。沒有計算過,就需要計算。
如果j已經超過了最後一個字元,那麼只有當i也超過最後一個字元時,才是匹配。patten為空的情況也包含在這裡。因為兩個字串匹配,最終肯定是要一起結束判斷的。
如果還沒有判斷完,就分為兩種情況。
第一種是帶星號的。這是j後面至少還需要有一個字元,即j<len(pattern)-1且pattern[j+1] == '*'
此時匹配又分為兩種情況:1)text中有0個*前面的字元,那麼此時的dp(i,j)直接等於dp(i,j+2),即*和他前面的不需要再判斷。
2)text中有多個1或多個*前面的字元,那麼此時首先須保證text[i]和text[j]匹配,然後再把text[i]去掉後判斷即可。即text[i+1:]與pattter[j:]是否匹配
第二種情況是單字元的匹配,即沒有星號的匹配。j可能等於pattern最後一個字元位置(因為大於最後一個字元位置的情況在前面被排除了)或pattern[j+1]不是星號。此時只要i還沒越界,切pattern[j]==text[i]或.即可。呢麼dp(i,j) == dp(i+1,j+1),即當前字元text[i]和pattern[j]匹配,只要後面也匹配即可。
每次把結果儲存起來,可以方便下次如果用到同樣的數的話不用再次重複計算,大大提高效率
class Solution(object):
def isMatch(self, text, pattern):
memo = {}
def dp(i, j):
if (i, j) not in memo:
if j == len(pattern):
ans = i == len(text)
else:
first_match = i < len(text) and pattern[j] in {text[i], '.'}
if j+1 < len(pattern) and pattern[j+1] == '*':
ans = dp(i, j+2) or first_match and dp(i+1, j)
else:
ans = first_match and dp(i+1, j+1)
memo[i, j] = ans
return memo[i, j]
return dp(0, 0)
第二種方法:
遞迴
class Solution(object):
def isMatch(self, s, p):
"""
:type s: str
:type p: str
:rtype: bool
"""
#如果只有.只需要一個元素一個元素比較,或者相等或者p中是.
#如果有*,*要與前一個元素組合起來比較
#因為採用遞迴形式,因此分為兩種情況,第二個字元是*
#第二個字元不是*(又包括只有一個字元和第二個字元不是*兩種情況)
#先處理特殊情況
if not p: #包括p為None和p的長度為0兩種情況
return not s #若s也為空則匹配,否則不匹配
#第一個字元匹配,因為此時p不為空,所以s也不能為空
#或者等於p[0],或者為‘.’
first_match = bool(s) and p[0] in (s[0],'.')
if len(p) >= 2 and p[1]=='*':
#第二個字元是*時,他前面的字母可以出現0次,此時只需要直接把*和前面的字元去掉遞迴即可
#或者是它前面的字元出現好多次,此時只要第一個字元匹配,然後每次去掉一個s的字母與原來的模式p匹配即可
return self.isMatch(s,p[2:]) or (first_match and self.isMatch(s[1:],p))
else:
#p的長度為1(因為0已經在最開始排除) 或者第二個字元不是*
#與沒有*時一樣,只要第一個一樣,然後去掉首字母后在比較,都相等則匹配
return first_match and self.isMatch(s[1:],p[1:])
相關文章
- Leetcode 10. 正規表示式匹配LeetCode
- leetcode - 正規表示式匹配LeetCode
- LeetCode 不只是題解(10.正規表示式匹配[困難])LeetCode
- 正規表示式匹配原理
- [譯]正規表示式匹配
- 字串——正規表示式匹配字串
- iOS正規表示式匹配iOS
- [LeetCode] Regular Expression Matching 正規表示式匹配LeetCodeExpress
- LeetCode-10. 正規表示式匹配(Python-re包)LeetCodePython
- 演算法之字串——正規表示式匹配演算法字串
- 正規表示式支配匹配模式模式
- JavaScript匹配中文正規表示式JavaScript
- 模式匹配與正規表示式模式
- Swift 正規表示式匹配NSRegularExpressionSwiftExpress
- python 正規表示式匹配Python
- 匹配html標籤正規表示式HTML
- 匹配空白字元正規表示式字元
- 匹配 XML 檔案正規表示式XML
- 匹配 HTML 標籤正規表示式HTML
- 匹配空行正規表示式程式碼
- 常用正規表示式匹配模式(java)模式Java
- JavaScript匹配註釋正規表示式JavaScript
- [JavaScript] 正規表示式單次匹配與多次匹配JavaScript
- JavaScript權威指南(10)——正規表示式的模式匹配JavaScript模式
- 匹配iphone手機序列正規表示式iPhone
- 匹配HTML註釋的正規表示式HTML
- 匹配A股程式碼的正規表示式
- 正規表示式匹配標點符號符號
- 匹配HTML標籤的正規表示式HTML
- 正規表示式匹配雙位元組字元字元
- js正規表示式如何匹配註釋JS
- 匹配javascript註釋的正規表示式JavaScript
- Oracle正規表示式匹配中文的方法Oracle
- 匹配正負小數正規表示式程式碼
- LeetCode題解(Offer19):正規表示式匹配的*和.實現(Python)LeetCodePython
- 過目不忘 JS 正規表示式JS
- 匹配視訊連結地址正規表示式
- 匹配純英文字元正規表示式字元