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)繼續移動和比較,得到最終匹配結果:
好辣,至此我們就得到期望的匹配結果了,整個過程是不是很好理解很好懂呢,相信你已經看懂了。。