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

d1e38a6fff32221d5e7b97189e3f4a66.png

前言

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

  1. 模式串主串進行比較
  • 從前往后比較
  • 從后往前比較


2. 匹配時,比較主串模式串的下一個位置
3. 失配時,

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

前面的 BFKMP 算法,都是屬于規規矩矩從前向后的操作,后者僅在尋找模式串的合適位置上進行了優化,而 BM 算法的操作就顯得騷了很多,它的優化點在于: 1. 從后往前比較 2. 失配時,尋找的是主串中合適的位置

算法介紹與分析

關于算法的介紹和分析,網上有很多解釋,這里推薦一下阮一峰的字符串匹配的Boyer-Moore算法,很清楚的講解了整個優化的思路,可以先看完理解了再往下看,因為下面主要介紹一下壞字符規則好后綴規則需要的數據結構的手工求法以及代碼實現。

壞字符規則

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

fa7aba71dc084f8e03bfc4f0673e4254.png

假設字符串的字符集不是很大,用長度為256的數組來存儲,并且初值賦值為-1。數組的下標對應字符的 ASCII 碼值,數組中存儲這個字符在模式串中出現的位置。這里要特別說明一點,如果壞字符在模式串里多處出現,選擇最靠后的那個,因為這樣不會讓模式串滑動過多,導致本來可能匹配的情況被滑動略過。

好后綴規則

好后綴規則體現在如何求出 suffixprefix 兩個數組以及移動規則

suffix 數組

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

22ea58a0864f6c36f162e2ae1ca4ce49.png

prefix 數組

同樣的,key值表示的是后綴子串的長度,而value值表示的是模式串中,是否有和該長度下后綴子串相同的前綴子串,是的話為 true,否則為 false,如下圖:

569286d7a67f58eeaa1baafd95a26d1d.png

移動規則

移動規則總結如下

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

下圖分別對應三種情況:

b2006052fcf14ae06e99b83833904a32.png

66a65d8d86c0d972d44d1fa05dea25ed.png

f7ccb9f60d1db44906d211c544236ece.png

代碼實現

整體邏輯框架

參考字符串匹配的思路

  1. 仍然需要進行主串模式串的字符對比,所以需要兩個指針 ij 分別指向主串模式串,記錄位置 需要一個循環來重復進行匹配操作,此時思考終止條件:
    1. i 指向主串每次匹配的合適位置,從前往后掃描;j 指向模式串的尾部,從后往前掃描。考慮極端情況:主串模式串對比完,仍然無法匹配。此時,i 的位置一定小于等于 主串長度 n模式串長度 m 的差值。具體可看下圖。
  2. 每次模式串從后往前與主串進行匹配,這也需要一個內層循環來驅動指針j 如果匹配,只需要繼續移動匹配位置即可
  3. 如果失配,分別根據壞字符規則好后綴規則計算出 i 需要移動的位置,選擇兩個值當中最大的,重新計算 i 的值,重復進行匹配。

ec50bf934bf21ceeae232b83eb2062a3.png

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

4749888be49776f8ae4b33c28d2f7bbc.png

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

求壞字符散列表

這個就沒有什么可以多說的了,只要參考上面分析的,一步一步寫出代即可:

e1866ea5e0d34677d729bc22394df7ea.png

求好后綴記錄數組 suffixprefix

拿下標從 0i 的子串(i 可以是 0m-2)與整個模式串,求公共后綴子串。如果公共后綴子串的長度是 k,那就記錄 suffix[k]=jj 表示公共后綴子串的起始下標)。如果 j 等于 0,也就是說,公共后綴子串也是模式串的前綴子串,就記錄 prefix[k]=true。可以自己動下手,模擬下代碼的運行,尤其注意中k值的運用,很巧妙。

b8b3ec450826152ff498b915b3a0a714.png

求好后綴移動步數

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

1ffb8c377c0cee85d78682859aec01eb.png

總結

總的來說,BM算法另辟蹊徑,通過從后往前的匹配的思路,加上壞字符規則好后綴規則來優化移動的步數,從而提高算法的匹配效率。

后記

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

  • 字符串匹配算法(一)——BF算法
  • 字符串匹配算法(二)——KMP算法
  • 字符串匹配算法(三)——BM算法
  • 字符串匹配算法(四)——Sunday算法

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/443237.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/443237.shtml
英文地址,請注明出處:http://en.pswp.cn/news/443237.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

遠程mysql定時刪除數據_mysql定時備份數據庫 刪除歷史文件 將備份數據庫傳送到另外服務器...

定時備份數據庫腳本并壓縮刪除歷史文件1.創建備份腳本vim mysql-backup.sh#!/bin/bashbakdate %y-%m-%d-%Htool/usr/local/mysql/bin/mysqldump$tool -uroot -p密碼 --lock-all-tables --all-databases | gzip > /路徑/$bak\.sql.gzfind 路徑 -name "name_*.sql.gz&q…

python input 拖入路徑 去除轉義 空格_python學習筆記(基礎-2)(轉載)

1.輸出用print()在括號中加上字符串,就可以向屏幕上輸出指定的文字。2.輸入如果要讓用戶從電腦輸入一些字符怎么辦?Python提供了一個input(),可以讓用戶輸入字符串,并存放到一個變量里。輸入是Input,輸出是Output&…

mysql和mdy_Liunx下安裝MySql

1.安裝數據庫:執行命令 yum -y install mysql-server2.啟動數據庫:安裝完畢,執行命令service mysqld start3.登錄數據庫:mysql -u root -p回車后輸入密碼(mysql的默認用戶名是root,密碼為空)4.使用數據庫:登…

python websocket服務器https_Socket與WebSocket以及http與https重新總結

Socket與WebSocket以及http與https重新總結一.Socket網絡中的Socket是一個抽象的接口 ,而是為了方便使用TCP或UDP而抽象出來的一層 ,可以理解為網絡中連接的兩端。通常被叫做套接字接口.二.WebSocketWebSocket就是其中一種,是為了創建一種雙向…

python微博評論爬蟲_詳解用python寫網絡爬蟲-爬取新浪微博評論 基于Python的新浪微博爬蟲研究...

怎樣爬取新浪微博的評論信息針對八爪魚在微博的應用上,除了用戶信息之外還包括話題內容方面的采集,目前絕大多數企業均在微博設有官方微博,八爪魚可以協助企業快速及時的抓取與企業產品相關聯的話題信息,規則市場內有配置好的規則…

韓順平 mysql sqlhelper類_(最全)韓順平jsp購物車源代碼(包含數據庫)

【實例簡介】韓順平的jsp購物車項目,所有源碼都在,包含數據庫,是網絡上最全的【實例截圖】【核心代碼】myshopping└── myshopping├── myshopping│ ├── src│ │ ├── com│ │ │ └── hsp│ │ │ ├── domain│ │ │ │ ├── B…

c#和python更適合爬蟲_python在爬蟲方面有哪些優勢呢?

python是一門非常不錯的編程語言,通俗易懂、適合零基礎入門,尤其是爬蟲領域有著獨特的優勢,成為了首選編程語言。Python是一種計算機程序設計語言,是一種動態的、面向對象的腳本語言。Python最初被設計用于編寫自動化腳本(shell)&…

mysql創建獨立表空間_InnoDB獨立表空間

在查看MySQL的數據庫文件的時候會發現,MyISAM存儲引擎類型的表會有三個文件,*.frm,*.MYD,*.MYI,但是InnoDB存儲引擎的文件只有一個*.frm,原來是因為InnoDB沒有開啟獨立表空間,執行如下命令可以看到:mysql&g…

python os模塊方法_python os模塊方法總結

在python中os是一個非常常用的模塊,下面是對os中方法的總結(實驗為Mac環境)1 . os.name :輸出字符串指示使用的平臺,windows是nt, linux/unix/mac是posix>>> os.nameposix>>>2 . os.getcwd() :獲取當前目錄>>> …

java button中文亂碼_java解決中文亂碼的幾種寫法

工作中總會遇到中文亂碼問題,以導出文件,文件名稱是中文的話,下載下來的文件名稱會亂碼問題,總結了幾種解決文件名亂碼的寫法,僅供參考。首先定義一個漢語字符串String zhName "錯誤碼模板";一、java.net.U…

java jframe添加面板_JFrame添加組件的兩種方式

對JFrame添加組件有兩種方式:1) 用getContentPane()方法獲得JFrame的內容面板,再對其加入組件:frame.getContentPane().add(childCompontent)常分開來寫Container containergetContentPanel();(隱式的this.getContentPanel()) ;得到jframe的內…

java 德生讀卡器對接程序_德生TSW-F4 社保卡讀卡器.rar

【實例簡介】德生TSW-F4 社保卡讀卡器測試程序以及動態庫,出廠自帶程序【實例截圖】【核心代碼】b79d6d98-2fcb-4e20-ab26-8f7aa14b320c└── 德生TSW-F4 社保卡讀卡器├── TSW-F4 U系列讀寫器隨機軟件_20120907│ ├── Dll│ │ ├── F4.h│ │ ├…

ios 數組越界奔潰庫_iOS中防止數組越界之后發生崩潰

在iOS開發中有時會遇到數組越界的問題,從而導致程序崩潰。為了防止程序崩潰,我們就要對數組越界進行處理。通過上網查資料,發現可以通過為數組寫一個分類來解決此問題。基本思路:為NSArray寫一個防止數組越界的分類。分類中利用ru…

java map與set的區別_Java中的Set,List,Map的區別是什么?

對JAVA的集合的理解是想對于數組數組是大小固定的,并且同一個數組只能存放類型一樣的數據(基本類型/引用類型)JAVA集合可以存儲和操作數目不固定的一組數據。所有的JAVA集合都位于 java。util包中!JAVA集合只能存放引用類型的的數據,不能存放…

java怎么使用泛型_java泛型 7 泛型的基本介紹和使用

現在開始深入學習Java的泛型了,以前一直只是在集合中簡單的使用泛型,根本就不明白泛型的原理和作用。泛型在java中,是一個十分重要的特性,所以要好好的研究下。一、泛型的基本概念泛型的定義:泛型是JDK 1.5的一項新特性…

java鋁輪_為速度而生 JAVA Fuoco鋁合金氣動公路

人類在追求速度的歷史上一直在不斷創新,從兩個輪子的自行車,到四個輪字的汽車,再到螺旋槳的飛機,追求速度是人類與生俱來的天性。就如同公路車的用途非常多,綜合型公路車、耐力型公路車、爬坡型公路車,但唯…

erlang mysql性能瓶頸,Erlang Mysql:如何防止SQL注入

Im very new to erlang and I need to code something which inserts rows in a MySQL Database.How can I prevent SQL Injections with Erlang? Is there also something like prepared statements in other Languages or how should I do it?Thanks for your replies.解決…

下列哪個不是java的數據類型_下面哪個不是Java基本數據類型?()

采集血標本時,錯誤的操作是A.血清標本應注入干燥試管B.生化檢驗標本在空腹時采集試比較脂肪酸β-氧化與生物合成的差異。調節水平衡的激素主要是A.胰島素 B.甲狀旁腺激素 C.血管升壓素 D求比50克多5克的數是多少?列式是…

Java jpa 字段限制_Java-JPA:僅更新特定字段

我有同樣的問題,正如Deinum先生所指出的,答案是否定的,您不能使用save。 主要問題是Spring Data不知道如何處理null。 是否設置了空值,還是因為需要將其刪除而設置了空值?現在從您的問題來看,我認為您也有同…

java excel中刪除兩列_Java 插入、隱藏/顯示、刪除Excel行或列

概述操作Excel工作表時,對表格中的行或列數據可執行,包括插入、隱藏、顯示、刪除等在內的多種操作需求,本文將通過Java代碼示例演示每種操作的具體實現方法。文中方法使用了Java Excel類庫(Free Spire.XLS for Java 免費版),可通過…