給你乙個字串s
和乙個字元規律p
,請你來實現乙個支援'.'
和'*'
的正規表示式匹配。
所謂匹配,是要涵蓋 整個 字串 s的,而不是部分字串。'.' 匹配任意單個字元'*' 匹配零個或多個前面的那乙個元素
輸入:s = "aa"p = "a"輸出:false解釋:"a" 無法匹配 "aa" 整個字串。
輸入:s = "aa"
p = "a*"
輸出: true
解釋: 因為 '*' 代表可以匹配零個或多個前面的那乙個元素, 在這裡前面的元素就是 'a'。因此,字串 "aa" 可被視為 'a' 重複了一次。
輸入:s = "ab"p = ".*"輸出:true解釋:".*" 表示可匹配零個或多個('*')任意字元('.')。
輸入:s = "aab"
p = "c*a*b"
輸出: true
解釋: 因為 '*' 表示零個或多個,這裡 'c' 為 0 個, 'a' 被重複一次。因此可以匹配字串 "aab"。
題目中的匹配是乙個「逐步匹配」的過程:我們每次從字串 p 中取出乙個字元或者「字元 + 星號」的組合,並在 s 中進行匹配。對於 p 中乙個字元而言,它只能在s 中匹配乙個字元,匹配的方法具有唯一性;而對於 p 中字元 + 星號的組合而言,它可以在 s 中匹配任意自然數個字元,並不具有唯一性。因此我們可以考慮使用動態規劃,對匹配的方案進行列舉。輸入:s = "mississippi"p = "mis*is*p*."輸出:false
我們用f[i][j] 表示 s 的前 i 個字元與p 中的前j 個字元是否能夠匹配。在進行狀態轉移時,我們考慮 p 的第j 個字元的匹配情況:
也就是說,如果s 的第i 個字元與 p 的第 j 個字元不相同,那麼無法進行匹配;否則我們可以匹配兩個字串的最後乙個字元,完整的匹配結果取決於兩個字串前面的部分。
f[i][j]=f[i][j−2]
也就是我們「浪費」了乙個字元 + 星號的組合,沒有匹配任何 s 中的字元。
在匹配 1,2,3,⋯ 次的情況下,類似地我們有
如果我們通過這種方法進行轉移,那麼我們就需要列舉這個組合到底匹配了 s 中的幾個字元,會增導致時間複雜度增加,並且**編寫起來十分麻煩。我們不妨換個角度考慮這個問題:字母 + 星號的組合在匹配的過程中,本質上只會有兩種情況:
如果按照這個角度進行思考,我們可以寫出很精巧的狀態轉移方程:
在任意情況下,只要 p[j] 是 .,那麼p[j] 一定成功匹配s 中的任意乙個小寫字母。
最終的狀態轉移方程如下:
其中 matches(x,y) 判斷兩個字元是否匹配的輔助函式。只有當 y 是 . 或者x 和y 本身相同時,這兩個字元才會匹配。
動態規劃的邊界條件為f[0][0]=true,即兩個空字串是可以匹配的。最終的答案即為f[m][n],其中m 和 n 分別是字串s 和p 的長度。由於大部分語言中,字串的字元下標是從 0 開始的,因此在實現上面的狀態轉移方程時,需要注意狀態中每一維下標與實際字元下標的對應關係。
在上面的狀態轉移方程中,如果字串 p 中包含乙個字元+星號的組合(例如a*),那麼在進行狀態轉移時,會先將 a 進行匹配(當 p[j] 為 a 時),再將a* 作為整體進行匹配(當 p[j] 為 * 時)。然而,在題目描述中,我們必須將 a* 看成乙個整體,因此將 a 進行匹配是不符合題目要求的。看來我們進行了額外的狀態轉移,這樣會對最終的答案產生影響嗎?這個問題留給讀者進行思考。
class solution
}else }}
}return f[m][n];
}public boolean matches(string s, string p, int i, int j)
if (p.charat(j - 1) == '.')
return s.charat(i - 1) == p.charat(j - 1);}}
正規表示式匹配演算法
看 之美 之美中有個簡短而高效的正規表示式匹配演算法,這裡給一下簡單的實現,供學習使用。include include includeusing namespace std int match char regexp,char text int matchhere char regexp,char ...
演算法 正規表示式匹配
給你乙個字串 s 和乙個字元規律 p,請你來實現乙個支援 和 的正規表示式匹配。匹配任意單個字元 匹配零個或多個前面的那乙個元素 所謂匹配,是要涵蓋 整個 字串 s的,而不是部分字串。說明 s 可能為空,且只包含從 a z 的小寫字母。p 可能為空,且只包含從 a z 的小寫字母,以及字元 和 示例...
演算法 正規表示式匹配
單純做個記錄 題目會給我們輸入兩個字串s和p,s代表文字,p代表模式串,請你判斷模式串p是否可以匹配文字s。正則表達演算法問題只需要把住乙個基本點 看兩個字元是否匹配,一切邏輯圍繞匹配 不匹配兩種情況展開即可。動態規劃演算法的核心就是 狀態 和 選擇 狀態 無非就是i和j兩個指標的位置,選擇 就是p...