javascript
diff算法阮一峰_【重学数据结构与算法(JS)】字符串匹配算法(三)——BM算法
前言
文章的一開頭,還是要強(qiáng)調(diào)下字符串匹配的思路
- 從前往后比較
- 從后往前比較
2. 匹配時(shí),比較主串和模式串的下一個(gè)位置
3. 失配時(shí),
- 在模式串中尋找一個(gè)合適的位置
- 如果找到,從這個(gè)位置開始與主串當(dāng)前失配位置進(jìn)行比較
- 如果未找到,從模式串的頭部與主串失配位置的下一個(gè)位置進(jìn)行比較
- 在主串中找到一個(gè)合適的位置,重新與模式串進(jìn)行比較
前面的 BF 和 KMP 算法,都是屬于規(guī)規(guī)矩矩從前向后的操作,后者僅在尋找模式串的合適位置上進(jìn)行了優(yōu)化,而 BM 算法的操作就顯得騷了很多,它的優(yōu)化點(diǎn)在于: 1. 從后往前比較 2. 失配時(shí),尋找的是主串中合適的位置
算法介紹與分析
關(guān)于算法的介紹和分析,網(wǎng)上有很多解釋,這里推薦一下阮一峰的字符串匹配的Boyer-Moore算法,很清楚的講解了整個(gè)優(yōu)化的思路,可以先看完理解了再往下看,因?yàn)橄旅嬷饕榻B一下壞字符規(guī)則和好后綴規(guī)則需要的數(shù)據(jù)結(jié)構(gòu)的手工求法以及代碼實(shí)現(xiàn)。
壞字符規(guī)則
運(yùn)用壞字符規(guī)則,在算法里主要體現(xiàn)在生成一張散列表,表的key值是字符集里每個(gè)字符的ASCII碼值,value值是模式串中該字符的位置,舉個(gè)栗子:
假設(shè)字符串的字符集不是很大,用長度為256的數(shù)組來存儲(chǔ),并且初值賦值為-1。數(shù)組的下標(biāo)對(duì)應(yīng)字符的 ASCII 碼值,數(shù)組中存儲(chǔ)這個(gè)字符在模式串中出現(xiàn)的位置。這里要特別說明一點(diǎn),如果壞字符在模式串里多處出現(xiàn),選擇最靠后的那個(gè),因?yàn)檫@樣不會(huì)讓模式串滑動(dòng)過多,導(dǎo)致本來可能匹配的情況被滑動(dòng)略過。
好后綴規(guī)則
好后綴規(guī)則體現(xiàn)在如何求出 suffix 和 prefix 兩個(gè)數(shù)組以及移動(dòng)規(guī)則。
suffix 數(shù)組
key值表示的是后綴子串的長度,value值表示的是在模式串中跟好后綴 S 相匹配的最后一個(gè)子串 S' 的首字母在模式串中的key值,如下圖:
prefix 數(shù)組
同樣的,key值表示的是后綴子串的長度,而value值表示的是模式串中,是否有和該長度下后綴子串相同的前綴子串,是的話為 true,否則為 false,如下圖:
移動(dòng)規(guī)則
移動(dòng)規(guī)則總結(jié)如下
- 在模式串中尋找跟好后綴 S 相匹配的最后一個(gè)子串 S'
- 如果找到,將模式串移動(dòng)到使得 S' 和主串對(duì)齊的位置
- 如果找不到,再尋找模式串的前綴子串中是否有和 好后綴 S 的后綴子串匹配的位置,滑動(dòng)模式串以對(duì)齊。
- 如果仍然找不到,則將模式串移動(dòng)至主串與模式串末尾對(duì)齊的下一個(gè)位置
下圖分別對(duì)應(yīng)三種情況:
代碼實(shí)現(xiàn)
整體邏輯框架
參考字符串匹配的思路
根據(jù)以上分析可以寫出整個(gè)的邏輯框架代碼:
框架寫好后,接下來就是完善三個(gè)輔助函數(shù)即可
求壞字符散列表
這個(gè)就沒有什么可以多說的了,只要參考上面分析的,一步一步寫出代即可:
求好后綴記錄數(shù)組 suffix 和 prefix
拿下標(biāo)從 0 到 i 的子串(i 可以是 0 到 m-2)與整個(gè)模式串,求公共后綴子串。如果公共后綴子串的長度是 k,那就記錄 suffix[k]=j(j 表示公共后綴子串的起始下標(biāo))。如果 j 等于 0,也就是說,公共后綴子串也是模式串的前綴子串,就記錄 prefix[k]=true。可以自己動(dòng)下手,模擬下代碼的運(yùn)行,尤其注意中k值的運(yùn)用,很巧妙。
求好后綴移動(dòng)步數(shù)
根據(jù)上面此步的算法分析,也可以寫出:
總結(jié)
總的來說,BM算法另辟蹊徑,通過從后往前的匹配的思路,加上壞字符規(guī)則和好后綴規(guī)則來優(yōu)化移動(dòng)的步數(shù),從而提高算法的匹配效率。
后記
“字符串匹配算法”是“重學(xué)數(shù)據(jù)結(jié)構(gòu)與算法”系列筆記:
- 字符串匹配算法(一)——BF算法
- 字符串匹配算法(二)——KMP算法
- 字符串匹配算法(三)——BM算法
- 字符串匹配算法(四)——Sunday算法
總結(jié)
以上是生活随笔為你收集整理的diff算法阮一峰_【重学数据结构与算法(JS)】字符串匹配算法(三)——BM算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java完全解耦_java-完全解耦
- 下一篇: Spring,ehcache整合报错