BM算法

BM算法(Boyer-Moore算法)是由Robert S. Boyer和J Strother Moore於1997年發明的一種字符串匹配算法,該算法在實際實踐中會比KMP算法效率高,因爲BM算法即使在最壞情況下其時間複雜度也爲O(N),BM算法不僅算法效率高,而且構思非常巧妙,也很容易理解,下面我們來舉例說明BM算法的運行過程:

匹配過程:

1)首先,字符串與搜索詞頭部對齊,從尾部字符開始比較


這裏跟KMP有很大的不同,就在於從尾部字符開始比較,這是一個非常巧妙的做法,很容易想到,如果對於尾部字符都不匹配的話,那麼我們只要一次比較,就可以知道前面相應長度的字符必定不是期望的結果。

2)“S”與“E”不匹配,我們就將“S”稱作“壞字符(bad character)”,即不匹配的字符,這時就可以將搜索詞直接往後移動幾位,這一過程被稱作壞字符引起的模式滑動,那麼具體應該移動多少位呢?這裏存在一個移動規則叫做壞字符規則,規則如下:

step_bad = pos1 - pos2                        公式1

其中,step_bad表示向後移動位數;pos1表示壞字符的位置;pos2表示壞字符在搜索詞中出現的最右位置

當然,有時也會出現壞字符不包含在搜索詞中,那麼這時pos2等於-1;

現在,我們來計算下面對上面的壞字符“S”,我們到底要往後移動多少位?

由於“S”對應的出現在搜索詞的第6位(從0開始索引),所以pos1 = 6;

而由於“S”在搜索詞中並未出現,所以pos2 = -1;

於是代入公式1可得:step_bad = 6-(-1)= 7;

於是移動7位變成如下:


3)同樣的,依然從尾部開始比較,並且利用同樣的移動規則,接下我們要移動6-4=2位,得到如下:


4)這時,出現了第一個匹配字符,同上依次比較和移動下去,會得到如下形式:


看到上圖中,得到“MPLE”匹配字符串,我們把這個字符串成爲“好後綴(good suffix)”,即所有尾部匹配的字符串;注意,“MPLE”,“PLE”,“LE”,“E”等都是好後綴;

關於好後綴,這裏同樣存在一個關於好後綴的規則:

step_good = pos1 - pos2                   公式2

其中,step_good爲後移位數;pos1表示好後綴的位置;pos2表示好後綴在搜索詞中剩餘部分出現的最右位置;

當然,如果好後綴在搜索詞中沒有再次出現,設爲-1;

5)再繼續比較,變成下面:


上圖中“I”與“A”不匹配,所以“I”是壞字符,根據壞字符規則,應該往後移動2-(-1)=3位,但是這裏有一個容易忽略的重要問題,那就是3就是我們的最優移法麼?答案是不一定,爲什麼?因爲這時我們已經有了好後綴夾雜在裏面,我們還需要考慮好後綴規則,這樣結合得到的纔是最優移法,那麼根據好後綴規則有:

所有的好後綴:“MPLE”,“PLE”,“LE”,“E”,只有“E”在“EXAMPL”中出現,所以後移6-0=6位,這個值顯然要比用壞字符規則求出的值要大,那我們到底是要移動3還是6呢?BM算法的做法是兩者取最大者,即每次後移的位數,取兩個規則中的較大者,所以我們應該往後移動6位:


這裏要注意的是:不論是好後綴規則還是壞字符規則,他們的移動位數都只與搜索詞(KMP中叫模式串)有關,而與原字符串(KMP中叫文本串)無關;

6)繼續作尾部比較,有:


發現“P”和“E”不匹配,因此“P”是壞字符,根據壞字符規則,應該移動6-4=2位;這時不考慮好後綴規則,爲什麼呢,因爲一開始從尾部字符就匹配失敗,那麼就還未得到好後綴,所以只考慮壞字符規則;

7)繼續移動和比較,得到最終匹配結果:


好辣,至此我們就得到期望的匹配結果了,整個過程是不是很好理解很好懂呢,相信你已經看懂了。。



發佈了139 篇原創文章 · 獲贊 305 · 訪問量 53萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章