Boyer-Moore字符串搜索(BM算法)的Python實現


BM算法根據兩個判據來進行字符串匹配,分別是“壞字符規則”和‘好后綴規則",其中好后綴規則可以單獨使用,算法的圖解可以參照下面這篇博文:

https://www.cnblogs.com/wxgblogs/p/5701101.html

 

 

采用Python語言對BM算法進行實現,實現過程分為3個函數,主循環函數和兩個判據的數組生成函數。

 1 def my_BM(t,p):  2     '''bm算法的自我實現,在t串中匹配p串,從模式串的尾部開始匹配'''
 3     '''需要壞字符數組badchar[]和好后綴數組goodsuffix[]  4  每次失配后,根據兩判據中最大的值移動p串,比較指針移動至最后'''
 5     BadChar=BClist(p)  6     GoodSuffix=GSlist(p)  7     tlen,plen=len(t),len(p)  8     if tlen<plen:  9         return -1
10     i,k=plen-1,plen-1   #從p串尾部開始比較
11     move=0 12     while i<tlen and k>=0: 13         if t[i]==p[k]: 14             i,k=i-1,k-1
15         else: 16             BCmove=k-BadChar[ord(t[i])] if BadChar[ord(t[i])]!=-1  else plen 17             move=max(GoodSuffix[k],BCmove)   #滑動位數
18             i,k=i+move+plen-1-k,plen-1
19     if k<=0: 20         return i+1
21     return -1
22             
23 
24 def BClist(p): 25     '''產生壞字符的失配移動表 26  j處失配,p串整體右移j-bc[T[j]]位'''
27     bc=[-1]*128   #標准ACCII表,可顯示128個常用字符
28     plen=len(p) 29     for i in range(plen): 30         bc[ord(p[i])]=i  #利用ord--chr函數的互相轉化,間接直接將字符作為下標
31     return bc 32 
33 def GSlist(p): 34     '''產生好后綴方法的失配移動表,若i處失配,則分三種:相應地跳過字符個數逐漸變大 35  1. 已匹配成功的字符串形成的后綴gs,在p串中x存在相等的子串,則將p串右移i-x+1; 36  2. 條件1不成立,則在p的前綴中尋找gs的后綴相等的最大串,設后綴頭在j,這一步類似於kmp的尋找最大相等前后綴,將p串右移j位; 37  3. 條件1,2都不成立,本輪比較失敗,將p串整體移動p長度m'''
38     plen=len(p) 39     GS=[plen]*plen  #初始化數組,並直接置於條件3的值
40     GS[plen-1]=1   #好后綴規則可以單獨使用,它是基於已匹配的字符進行優化跳過,若首次匹配就失敗,則應該只移動p串一位
41     for i in range(plen-1):    #i處失配 
42         #條件2,求i之后的后綴串,其在p串前綴中的最大相等前綴
43         #雖然也是求最大相等前后綴,但與kmp不同,kmp求的是前綴子串中的最大相等前后綴,而好后綴算法中求的是整個p串的最大相等前后綴,只是對該前后綴的長度做了限制
44         k=0 45         j=i+1
46         while j<plen: 47             if p[k]==p[j]: 48                 k,j=k+1,j+1
49             else: 50                 j=j-k+1
51                 k=0 52         if k!=0: 53             GS[i]=plen-1-k 54         #搜尋p串中是否還有與p[i+1:]相等的子串,即條件1
55         substr=find_last(p[:plen-1],p[i+1:]) #find_last(t,p)函數尋找t串中最后一個p串的起始位置,若沒有則返回-1 56         if substr!=-1: 57             GS[i]=i-substr+1
58     return GS

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM