tft每日頭條

 > 生活

 > 簡單匹配算法和樸素匹配算法

簡單匹配算法和樸素匹配算法

生活 更新时间:2024-12-19 20:06:58

下面使用動态規劃來實現簡單的正則表達式匹配。題目如下:

假設?可以匹配任意的一個字符,*可以匹配0到任意個字符,正則表達式隻能由數字,英文字母、?和*組成,字符串由英文字母和數字組成,編寫一個程序,給定一個滿足上述規則的正則表達式和字符串,返回正則表達式是否匹配該字符串。

以下是匹配的例子:

簡單匹配算法和樸素匹配算法(算法求解思路培養-10.動态規劃之簡單的正則表達式匹配算法)1

下面看看代碼如何寫。

用pattern = "hel?o"和 sentence = "hello"進行嘗試:

簡單匹配算法和樸素匹配算法(算法求解思路培養-10.動态規劃之簡單的正則表達式匹配算法)2

發現pattern[0] = sentence[0],則i和j分别 1,繼續判斷,直到i=3和j=3,如下圖所示:

簡單匹配算法和樸素匹配算法(算法求解思路培養-10.動态規劃之簡單的正則表達式匹配算法)3

此時pattern[3] != sentence[3],但由于pattern[i]此時的值為?,可以匹配任意一個字符,因此認為仍然匹配,i和j分别 1,繼續往下匹配。

定義表達式dp(i,j)為pattern[i:]和sentence[j:]是否匹配。從上述分析可以看出,如果

pattern[i] == sentence[j] 或者 sentence[j] == "?",則 dp[i][j] = dp[i 1][j 1]。

主要的困難在于*的處理。假設pattern="***bc",sentence="abc",那麼,對于第一個*号,可以有以下4種情形:

情形1:不匹配任何字符

簡單匹配算法和樸素匹配算法(算法求解思路培養-10.動态規劃之簡單的正則表達式匹配算法)4

情形2:匹配第一個字符

簡單匹配算法和樸素匹配算法(算法求解思路培養-10.動态規劃之簡單的正則表達式匹配算法)5

情形3:匹配前二個字符:

簡單匹配算法和樸素匹配算法(算法求解思路培養-10.動态規劃之簡單的正則表達式匹配算法)6

情形4:匹配前三個字符:

簡單匹配算法和樸素匹配算法(算法求解思路培養-10.動态規劃之簡單的正則表達式匹配算法)7

經過上述分析,可以得出結論:

dp[i][j] = U(dp[i 1][k]), k=j....N。 其中隻要有任意一個dp[i 1][k]為True,則

dp[i][j] = True

代碼編寫如下:

def simple_regex(mod,s,i,j): if i<len(mod) and j<len(s) and (mod[i] == s[j] or mod[i] == "?"): return simple_regex(mod,s,i 1,j 1) elif i == len(mod): return j == len(s) elif mod[i] == "*": for k in range(j,len(s) 1): if simple_regex(mod,s,i 1,k): return True return False print(simple_regex("a*b*c*d****e","athis is a boy and cow and welcome",0,0)) print(simple_regex( "*p*","help",0,0)) print(simple_regex( "*p*","papa",0,0)) print(simple_regex( "*p*","a",0,0)) print(simple_regex( "*p*","p",0,0)) print(simple_regex("he?p","p",0,0)) print(simple_regex("he?p","help",0,0)) print(simple_regex("he?p","heap",0,0)) print(simple_regex("he?p","healp",0,0)) print(simple_regex("*bb*","babbbc",0,0)) print(simple_regex("*bb*p","babbbc",0,0)) print(simple_regex("*bb*","babbbc",0,0)) print(simple_regex("***bb*","b",0,0))

程序輸出:

True True True False True False True True False True False True False

按照動态規劃的思路,增加緩存,同時将

for k in range(j,len(s) 1): if simple_regex(mod,s,i 1,k):

替換成遞歸的實現以提升效率,代碼如下:

pattern ="t*b*c*d****e" sentence = "this is a boy and cow and welcome" cache = [[-1 for i in range(len(sentence) 1)] for j in range(len(pattern) 1)] def simple_regex(mod,s,i,j): if not (cache[i][j] == -1): return cache[i][j] cache[i][j] = False if i<len(mod) and j<len(s) and (mod[i] == s[j] or mod[i] == "?"): cache[i][j] =simple_regex(mod,s,i 1,j 1) elif i == len(mod): cache[i][j] = j == len(s) elif mod[i] == "*": cache[i][j] = simple_regex(mod,s,i 1,j) or (j<len(s) 1 and simple_regex(mod,s,i,j 1)) return cache[i][j] print(wild_char(pattern,sentence,0,0))

解釋下上述代碼。

第13行,當mod[i]==‘*’時,我們将循環寫成了遞歸形式。simple_regex(mod,s,i 1,j)表示*号不匹配任何字符。simple_regex(mod,s,i,j 1)表示*号匹配一個字符後,進入下一次遞歸調用。通過這兩個遞歸組合就完成了

for k in range(j,len(s) 1): if simple_regex(mod,s,i 1,k):

達到的效果。

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关生活资讯推荐

热门生活资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved