阮一峰 字串匹配的Boyer Moore演算法

2021-06-14 02:37:53 字數 2557 閱讀 6348

但是,它並不是效率最高的演算法,實際採用並不多。各種文字編輯器的"查詢"功能(ctrl+f),大多採用 boyer-moore 演算法。

boyer-moore 演算法不僅效率高,而且構思巧妙,容易理解。1977 年,德克薩斯大學的 robert s. boyer 教授和 j strother moore 教授發明了這種演算法。

下面,我根據 moore 教授自己的例子來解釋這種演算法。

假定字串為"here is a ****** example",搜尋詞為"example"。

首先,"字串"與"搜尋詞"頭部對齊,從尾部開始比較。

這是乙個很聰明的想法,因為如果尾部字元不匹配,那麼只要一次比較,就可以知道前 7 個字元肯定不是要找的結果。

我們看到,"s"與"e"不匹配。這時,"s"就被稱為"壞字元"(bad character),即不匹配的字元。我們還發現,"s"不包含在搜尋詞"example"之中,這意味著可以把搜尋詞直接移到"s"的後一位。

依然從尾部開始比較,發現"p"與"e"不匹配,所以"p"是"壞字元"。但是,"p"包含在搜尋詞"example"之中。所以,將搜尋詞後移兩位,兩個"p"對齊。

我們由此總結出"壞字元規則":

後移位數 = 壞字元的位置 - 搜尋詞中的上一次出現位置

如果"壞字元"不包含在搜尋詞之中,則上一次出現位置為 -1。

以"p"為例,它作為"壞字元",出現在搜尋詞的第 6 位(從 0 開始編號),在搜尋詞中的上一次出現位置為4,所以後移 6 - 4 = 2 位。再以前面第二步的"s"為例,它出現在第 6 位,上一次出現位置是 -1(即未出現),則整個搜尋詞後移 6 - (-1) = 7 位。

依然從尾部開始比較,"e"與"e"匹配。

比較前面一位,"le"與"le"匹配。

比較前面一位,"ple"與"ple"匹配。

8.比較前面一位,"mple"與"mple"匹配。我們把這種情況稱為"好字尾"(good suffix),即所有尾部匹配的字串。注意,"mple"、"ple"、"le"、"e"都是好字尾。

比較前一位,發現"i"與"a"不匹配。所以,"i"是"壞字元"。

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

我們知道,此時存在"好字尾"。所以,可以採用"好字尾規則":

後移位數 = 好字尾的位置 - 搜尋詞中的上一次出現位置

計算時,位置的取值以"好字尾"的最後乙個字元為準。如果"好字尾"在搜尋詞中沒有重複出現,則它的上一次出現位置為 -1。

所有的"好字尾"(mple、ple、le、e)之中,只有"e"在"example"之中出現兩次,所以後移 6 - 0 = 6 位。

可以看到,"壞字元規則"只能移 3 位,"好字尾規則"可以移 6 位。所以,boyer-moore 演算法的基本思想是,每次後移這兩個規則之中的較大值。

更巧妙的是,這兩個規則的移動位數,只與搜尋詞有關,與原字串無關。因此,可以預先計算生成《壞字元規則表》和《好字尾規則表》。使用時,只要查表比較一下就可以了。

繼續從尾部開始比較,"p"與"e"不匹配,因此"p"是"壞字元"。根據"壞字元規則",後移 6 - 4 = 2 位。

阮一峰 字串匹配的Boyer Moore演算法

阮一峰 字串匹配的boyer moore演算法 但是,它並不是效率最高的演算法,實際採用並不多。各種文字編輯器的 查詢 功能 ctrl f 大多採用 boyer moore 演算法。boyer moore 演算法不僅效率高,而且構思巧妙,容易理解。1977 年,德克薩斯大學的 robert s.bo...

阮一峰的es6

1.let命令 塊級作用域 for迴圈 2.不存在變數提公升 3.暫時性死區 4.不允許重複宣告 5.為什麼需要塊級作用域 6.es6塊級作用域的巢狀 7.塊級作用域與函式宣告 8.do表示式 9.const命令 宣告常量 const的作用域與let命令相同 只在宣告所在的塊級作用域內有效 cons...

阮一峰 學習C語言的教材

我的c語言是自學的,這些年看過不少教材。下面,我對其中一些教材做個點評。1.how to think like a computer scientist c version 這是我讀過最易懂的c語言教材。2.c primer plus 上面這兩本,都是著名的c語言初級教材,都是厚厚的大部頭。我通讀過...