字符串匹配的 Boyer-Moore 算法

上一篇文章,我介紹了 字符串匹配的KMP算法算法

可是,它並非效率最高的算法,實際採用並很少。各類文本編輯器的」 查找」 功能(Ctrl+F),大多采用 Boyer-Moore 算法。編輯器

下面,我根據 Moore 教授本身的例子來解釋這種算法。3d

1.blog

假定字符串爲」HERE IS A SIMPLE EXAMPLE」,搜索詞爲」EXAMPLE」。字符串

2.效率

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

這是一個很聰明的想法,由於若是尾部字符不匹配,那麼只要一次比較,就能夠知道前 7 個字符確定不是要找的結果。文本編輯器

咱們看到,」S」 與」E」 不匹配。這時,「S」 就被稱爲」 壞字符」(bad character),即不匹配的字符。咱們還發現,」S」 不包含在搜索詞」EXAMPLE」 之中,這意味着能夠把搜索詞直接移到」S」 的後一位。im

3.d3

依然從尾部開始比較,發現」P」 與」E」 不匹配,因此」P」 是」 壞字符」。可是,」P」 包含在搜索詞」EXAMPLE」 之中。因此,將搜索詞後移兩位,兩個」P」 對齊。

4.

咱們由此總結出 「壞字符規則」:

後移位數 = 壞字符的位置 – 搜索詞中的上一次出現位置

若是」 壞字符」 不包含在搜索詞之中,則上一次出現位置爲 -1。

以」P」 爲例,它做爲」 壞字符」,出如今搜索詞的第 6 位(從 0 開始編號),在搜索詞中的上一次出現位置爲 4,因此後移 6 – 4 = 2 位。再之前面第二步的」S」 爲例,它出如今第 6 位,上一次出現位置是 -1(即未出現),則整個搜索詞後移 6 – (-1) = 7 位。

5.

依然從尾部開始比較,」E」 與」E」 匹配。

6.

比較前面一位,」LE」 與」LE」 匹配。

7.

比較前面一位,」PLE」 與」PLE」 匹配。

8.

比較前面一位,」MPLE」 與」MPLE」 匹配。咱們把這種狀況稱爲」 好後綴」(good suffix),即全部尾部匹配的字符串。注意,」MPLE」、」PLE」、」LE」、」E」 都是好後綴。

9.

比較前一位,發現」I」 與」A」 不匹配。因此,」I」 是」 壞字符」。

10.

根據」 壞字符規則」,此時搜索詞應該後移 2 – (-1)= 3 位。問題是,此時有沒有更好的移法?

11.

 

咱們知道,此時存在」好後綴」。因此,能夠採用 「好後綴規則」:

後移位數 = 好後綴的位置 – 搜索詞中的上一次出現位置

計算時,位置的取值以」 好後綴」 的最後一個字符爲準。若是」 好後綴」 在搜索詞中沒有重複出現,則它的上一次出現位置爲 -1。

全部的」 好後綴」(MPLE、PLE、LE、E)之中,只有」E」 在」EXAMPLE」 之中出現兩次,因此後移 6 – 0 = 6 位。

12.

 

能夠看到,」 壞字符規則」 只能移 3 位,」 好後綴規則」 能夠移 6 位。因此,Boyer-Moore 算法的基本思想是,每次後移這兩個規則之中的較大值。

更巧妙的是,這兩個規則的移動位數,只與搜索詞有關,與原字符串無關。所以,能夠預先計算生成《壞字符規則表》和《好後綴規則表》。使用時,只要查表比較一下就能夠了。

13.


繼續從尾部開始比較,」P」 與」E」 不匹配,所以」P」 是」 壞字符」。根據」 壞字符規則」,後移 6 – 4 = 2 位。

14.

從尾部開始逐位比較,發現所有匹配,因而搜索結束。若是還要繼續查找(即找出所有匹配),則根據」 好後綴規則」,後移 6 – 0 = 6 位,即頭部的」E」 移到尾部的」E」 的位置。

相關文章
相關標籤/搜索