萬用字元匹配 講解和python3實現

2021-09-03 01:27:36 字數 4917 閱讀 3051

給定乙個字串 (s) 和乙個字元模式 § ,實現乙個支援 『?』 和 『*』 的萬用字元匹配。

『?』 可以匹配任何單個字元。

『*』 可以匹配任意字串(包括空字串)。

兩個字串完全匹配才算匹配成功。

說明:s 可能為空,且只包含從 a-z 的小寫字母。

p 可能為空,且只包含從 a-z 的小寫字母,以及字元 ? 和 *。

示例 1:

輸入:s = 「aa」

p = 「a」

輸出: false

解釋: 「a」 無法匹配 「aa」 整個字串。

示例 2:

輸入:s = 「aa」

p = ""

輸出: true

解釋: '』 可以匹配任意字串。

示例 3:

輸入:s = 「cb」

p = 「?a」

輸出: false

解釋: 『?』 可以匹配 『c』, 但第二個 『a』 無法匹配 『b』。

示例 4:

輸入:s = 「adceb」

p = 「ab」

輸出: true

解釋: 第乙個 『』 可以匹配空字串, 第二個 '』 可以匹配字串 「dce」.

示例 5:

輸入:s = 「acdcb」

p = 「a*c?b」

輸入: false

需要明確的是 用「模式串」去匹配「字串」,迴圈是 模式串在外層迴圈

for p:

for s:

採用遞迴的思路 碰到 == *==特殊考慮

solve(i_s,i_p+1)  \  * 匹配0 個

or solve(i_s+1,i_p+1) \ *匹配結束

or solve(i_s+1,i_p)) * 繼續匹配下乙個

def

ismatch_brude_force

(s, p)

:"""

:type s: str

:type p: str

:rtype: bool

"""len_s=

len(s)

len_p=

len(p)

defsolve

(i_s,i_p)

:if i_s > len_s or i_p > len_p:

return

false

if i_s == len_s:

if i_p==len_p:

return

true

elif

len(

set(p[i_p:])

)==1and

set(p[i_p:])

.pop()==

"*":

return

true

else

:return

false

elif i_p==len_p:

return

false

if s[i_s]

==p[i_p]

or p[i_p]

=="?"

: i_s+=

1 i_p+=

1return solve(i_s,i_p)

elif p[i_p]

=="*"

:return solve(i_s,i_p+1)

or solve(i_s+

1,i_p+1)

or solve(i_s+

1,i_p)

else

:return

false

return solve(0,

0)

這位大佬寫的很好,有解釋

既然用到動態規劃,最重要的是設定初值 和找到遞推式

我們開始分析初值怎麼設;其實很簡單,把這個匹配問題可以想象成乙個矩陣dp,縱軸代表含有萬用字元的匹配字串s2, 橫軸代表要匹配的字串s1。假設現在s2=」a*b」, s1=」abc」 如圖:

對應空位就是截止到當前的 (i,j) 位置,兩字串是否匹配。匹配為 t(true),不匹配為 f(false),最後返回最右下角的值,就是當前兩個字串是否匹配的最終值;

現在我們要做的設定初值,所以我們大可多加一行和一列,來填充初值;s1既然是要匹配的,我們都設為 f(即dp[0][1]=f,dp[0][2]=f,dp[0][3]=f),表示當前還未開始匹配。而s2的初值,我們發現如果星號和a調換位置,星號可以匹配任意字串,所以dp[i][0]的值取決於該位置是否為星號和上乙個位置d[i-1][0]是否為t(其實就是上乙個位置是否也是星號),所以我們設定dp[0][0]為 t。所以形成下圖:

此時初值已經設定完畢,我們要找到遞推式;經區域性推算,我們發現遞推式應該有兩種,一種是當s2的字元是星號,另一種是s2的字元是非星號。

先看星號的情況:當要計算dp[2][1](即要匹配a和a時),我們發現是取決於dp[1][1](即a和a是否匹配),當要計算dp[2][2] (即要匹配a和ab時),是取決於dp[2][1] (即a*和a是否匹配)。抽象一下,星號和任意字元(0或多個)都匹配。所以字串截止到星號匹配的情況,取決於當前位置向上和向左的情況(即可以為0個字元,也可以為多個字元)。

所以此時遞推式為dp[i][j]=dp[i−1][j]||dp[i][j−1]dp[i][j]=dp[i−1][j]||dp[i][j−1]如圖:

再看非星號的情況:當要計算dp[3][2] (即要匹配ab和ab時),則取決於dp[2][1]和a[3][2] (即a和a是否匹配,同時b和b是否匹配);所以可以得到遞推式 dp[i][j] = dp[i-1][j-1]&&a[i][j]dp[i][j] = dp[i-1][j-1]&&a[i][j]。如圖:

主要是星號的匹配處理。遇到星號就跳過去,優先用星號後面的來匹配。如果星號後面的匹配不上,則用星號匹配乙個字元,再看星號後面的能否匹配上

def

ismatch_most_difficult

(s, p)

: scur, pcur, sstar, pstar =0,

0,none

,none

while scur <

len(s)

:if pcur <

len(p)

and p[pcur]

in[s[scur]

,'?']:

scur, pcur = scur+

1, pcur+

1elif pcur <

len(p)

and p[pcur]

=='*'

: pstar, pcur = pcur, pcur+

1 sstar = scur

elif pstar !=

none

: pcur = pstar +

1 sstar +=

1 scur = sstar

else

:return

false

while pcur <

len(p)

and p[pcur]

=='*'

: pcur +=

1return pcur >=

len(p)

Python3 正則匹配問題

python3通過re模組提供對正規表示式的支援。使用re的一般步驟是先將正規表示式的字串形式編譯為pattern例項,然後使用pattern例項處理文字並獲得匹配結果 乙個match例項 最後使用match例項獲得資訊,進行其他的操作。舉個例子 import re pattern re.compi...

python匹配linux萬用字元

有時候需要匹配linux中的萬用字元,例如 和?它們的含義為 匹配0個或多個字元 匹配任意單個字元。這和正規表示式中含義不一樣,在正規表示式中 匹配前乙個字元0次或者多次 匹配前乙個字元1次。這時候可以使用下面的函式,s表示需要匹配的字串,p表示含有萬用字元的字串。def match wildcar...

python3 匹配中文

1 usr bin env python2 coding utf 8 3 author leo 4 date 2017 9 27 5 6 78 910 import re11 1213 defget chinese color color name 14 color str u4e00 u9fff ...