【重學數據結構與算法(JS)】字符串匹配算法(三)——BM算法

前言

文章的一開頭,仍是要強調下字符串匹配的思路:html

  1. 模式串主串進行比較算法

    • 從前日後比較
    • 從後往前比較
  2. 匹配時,比較主串模式串的下一個位置
  3. 失配時,segmentfault

    • 模式串中尋找一個合適的位置數組

      • 若是找到,從這個位置開始與主串當前失配位置進行比較
      • 若是未找到,從模式串的頭部與主串失配位置的下一個位置進行比較
    • 主串中找到一個合適的位置,從新與模式串進行比較

前面的 BFKMP 算法,都是屬於規規矩矩從前向後的操做,後者僅在尋找模式串的合適位置上進行了優化,而 BM 算法的操做就顯得騷了不少,它的優化點在於:數據結構

  1. 從後往前比較
  2. 失配時,尋找的是主串中合適的位置

算法介紹與分析

關於算法的介紹和分析,網上有不少解釋,這裏推薦一下阮一峯的字符串匹配的Boyer-Moore算法,很清楚的講解了整個優化的思路,能夠先看完理解了再往下看,由於下面主要介紹一下壞字符規則好後綴規則須要的數據結構的手工求法以及代碼實現。框架

壞字符規則

運用壞字符規則,在算法裏主要體如今生成一張散列表,表的key值是字符集裏每一個字符的ASCII碼值,value值是模式串中該字符的位置,舉個栗子:函數

QQ20200119-202854.png

假設字符串的字符集不是很大,用長度爲256的數組來存儲,而且初值賦值爲-1。數組的下標對應字符的 ASCII 碼值,數組中存儲這個字符在模式串中出現的位置。這裏要特別說明一點,若是壞字符在模式串裏多處出現,選擇最靠後的那個,由於這樣不會讓模式串滑動過多,致使原本可能匹配的狀況被滑動略過。優化

好後綴規則

好後綴規則體如今如何求出 suffixprefix 兩個數組以及移動規則spa

suffix 數組

key值表示的是後綴子串的長度,value值表示的是在模式串中跟好後綴 S 相匹配的最後一個子串 S' 的首字母在模式串中的key值,以下圖:3d

QQ20200119-211057.png

prefix 數組

一樣的,key值表示的是後綴子串的長度,而value值表示的是模式串中,是否有和該長度下後綴子串相同的前綴子串,是的話爲 true,不然爲 false,以下圖:

QQ20200119-212509.png

移動規則

移動規則總結以下:

  • 模式串中尋找跟好後綴 S 相匹配的最後一個子串 S'

    • 若是找到,將模式串移動到使得 S'主串對齊的位置
    • 若是找不到,再尋找模式串前綴子串中是否有和 好後綴 S後綴子串匹配的位置,滑動模式串以對齊。
    • 若是仍然找不到,則將模式串移動至主串模式串末尾對齊的下一個位置

下圖分別對應三種狀況:

QQ20200119-215102.png
QQ20200119-220640.png
QQ20200119-221219.png

代碼實現

總體邏輯框架

參考字符串匹配的思路

  • 仍然須要進行主串模式串的字符對比,因此須要兩個指針 ij 分別指向主串模式串,記錄位置
  • 須要一個循環來重複進行匹配操做,此時思考終止條件:

    • i 指向主串每次匹配的合適位置,從前日後掃描;j 指向模式串的尾部,從後往前掃描。考慮極端狀況:主串模式串對比完,仍然沒法匹配。此時,i 的位置必定小於等於 主串長度 n模式串長度 m 的差值。具體可看下圖。
  • 每次模式串從後往前與主串進行匹配,這也須要一個內層循環來驅動指針j
  • 若是匹配,只須要繼續移動匹配位置便可
  • 若是失配,分別根據壞字符規則好後綴規則計算出 i 須要移動的位置,選擇兩個值當中最大的,從新計算 i 的值,重複進行匹配。

QQ20200120-202236.png

根據以上分析能夠寫出整個的邏輯框架代碼:

carbon.png

框架寫好後,接下來就是完善三個輔助函數便可

求壞字符散列表

這個就沒有什麼能夠多說的了,只要參考上面分析的,一步一步寫出代便可:

carbon的副本.png

求好後綴記錄數組 suffixprefix

拿下標從 0i 的子串(i 能夠是 0m-2)與整個模式串,求公共後綴子串。若是公共後綴子串的長度是 k,那就記錄 suffix[k]=jj 表示公共後綴子串的起始下標)。若是 j 等於 0,也就是說,公共後綴子串也是模式串的前綴子串,就記錄 prefix[k]=true。能夠本身動下手,模擬下代碼的運行,尤爲注意中k值的運用,很巧妙。

carbon的副本2.png

求好後綴移動步數

根據上面此步的算法分析,也能夠寫出:

carbon的副本3.png

總結

總的來講,BM算法另闢蹊徑,經過從後往前的匹配的思路,加上壞字符規則好後綴規則來優化移動的步數,從而提升算法的匹配效率。

後記

「字符串匹配算法」是「重學數據結構與算法」系列筆記:

相關文章
相關標籤/搜索