在這裡我所要想說的比kmp演算法高效的演算法是boyer-moore演算法。
在講解boyer-moore演算法之前,在這裡先回顧一下kmp演算法。
比如說有乙個字串"bbc abcdab abcdabcdabde",我想知道,裡面是否包含另乙個字串"abcdabd"。大部分情況下我們會使用kmp演算法去解:
首先,字串"bbc abcdab abcdabcdabde"的第乙個字元與搜尋詞"abcdabd"的第乙個字元,進行比較。因為b與a不匹配,所以搜尋詞後移一位。 2.
b與a不匹配,搜尋詞向後移一位。直到有一位搜尋詞相同。 3.
可以看到前6個數都是相同的,但是最後乙個數d與空格不相同。根據kmp演算法,搜尋詞向後移動一位。但是這就是kmp演算法效率低的地方,之前的6個數我們已經比較過了,已經不可能匹配了,但是kmp演算法還是重複的匹配。在後面講的boyer-moore演算法會有優化。
利用《部分匹配表》(partial match table)可以根據公式:
移動位數 = 已匹配的字元數 - 對應的部分匹配值;
算出向後移動的位數。
5. 部分匹配表例項:
"部分匹配"的實質是,有時候,字串頭部和尾部會有重複。比如,"abcdab"之中有兩個"ab",那麼它的"部分匹配值"就是2("ab"的長度)。搜尋詞移動的時候,第乙個"ab"向後移動4位(字串長度-部分匹配值),就可以來到第二個"ab"的位置。
boyer-moore演算法:
壞字元演算法:
其實boyer-moore演算法使用最多的是大部分軟體裡的「查詢演算法」。crtl+f4的功能。
注意:boyer-moore演算法是從後向前匹配的。這是乙個很聰明的想法,因為如果尾部字元不匹配,那麼只要一次比較,就可以知道前7個字元(整體上)肯定不是要找的結果。
如上面的情況:
boyer-moore是怎麼處理的呢?
我們看到,"c"與"d"不匹配。這時,"c"就被稱為"壞字元"(bad character),即不匹配的字元。我們還發現,"c"包含在搜尋詞"abcdabd"之中,這意味著可以把搜尋詞直接移到"c"的後一位。
我們看到,"d"與"空格不匹配。這時,空格就被稱為"壞字元"(bad character),即不匹配的字元。我們還發現,空格不包含在搜尋詞"abcdabd"之中,這意味著可以把搜尋詞直接移到空格的後一位。
而後面的「c」和「d」不相同,但是我們可以注意到壞字元「c」在搜尋詞「abcdabd」中,根據規則我們將搜尋詞中的「c」移動到壞字元處:
這樣,我們就找到了匹配的字串了。。
我們可以總結boyer-moore的壞字元演算法:
後移位數 = 壞字元的位置 - 搜尋詞中的上一次出現位置
即:壞字元「c」(上面的那乙個c)出現在搜尋詞的第6位(從0開始
),在搜尋詞中上一次出現的位置是2。所以6-2=4。
向後移動4位。
注意
boyer-moore演算法除了有」壞字元演算法「還有
」好字尾演算法「:
那麼好字尾演算法是什麼樣的情況呢?這裡,我們得換個例子:
如果出現這種情況:
"mple"與"mple"匹配。我們把這種情況稱為"好字尾"(good suffix),即所有尾部匹配的字串。注意,"mple"、"ple"、"le"、"e"都是好字尾。
比較"i"與"a"不匹配,那麼"i"就是壞字元。根據"壞字元規則",此時搜尋詞應該後移 2 - (-1)= 3 位。但是在這裡我們採用"好字尾演算法":
後移位數 = 好字尾的位置 - 搜尋詞中的上一次出現位置
此時,所有的"好字尾"(mple、ple、le、e)之中,只有"e"在"example"還出現在頭部,所以後移 6 - 0 = 6位。
"壞字元規則"只能移3位,"好字尾規則"可以移6位。所以,boyer-moore演算法的基本思想是,每次後移這兩個規則之中的較大值。
繼續從尾部開始比較,"p"與"e"不匹配,因此"p"是"壞字元"。根據"壞字元規則",後移 6 - 4 = 2位。
匹配完成。。。
比KMP演算法更簡潔,更高效的sunday演算法
kmp演算法中next陣列計算比較難懂,sunday演算法更高效,但是網路中各個版本都有bug,自己除錯的無錯誤的權當作筆記 sunday演算法 sunday演算法其實思想跟bm演算法很相似,只不過sunday演算法是從前往後匹配,在匹配失敗時關注的是文字串中參加匹配的最末位字元的下一位字元。如果該...
epoll比select高效的原因
select每次呼叫select 時都要傳入fds陣列,而epoll在核心維護了乙個等待佇列,每次呼叫epoll wait 時不需要傳入等待佇列進去,只在執行epoll ctl 時才更新等待佇列。降低了核心與使用者層的資料遷移 select 返回後每次都要遍歷所有被監視的檔案描述符,而epoll w...
MySQL比like語句更高效的寫法
like語句 select column from table where condition like keyword 事實上,可以使用 locate position 和 instr 這兩個函式來代替 一 locate語句 select column from table where locat...