七分钟理解什么是 KMP 算法
本文是介紹 什么是 BF算法、KMP算法、BM算法 三部曲之一。
KMP算法 內(nèi)部涉及到的數(shù)學(xué)原理與知識(shí)太多,本文只會(huì)對(duì) KMP算法 的運(yùn)行過(guò)程、 部分匹配表 、next數(shù)組 進(jìn)行介紹,如果理解了這三點(diǎn)再去閱讀其它有關(guān) KMP算法 的文章肯定能有個(gè)清晰的認(rèn)識(shí)。
以下的文字描述請(qǐng)結(jié)合視頻動(dòng)畫來(lái)閱讀~
視頻地址:https://www.bilibili.com/video/av60334201/
定義
Knuth-Morris-Pratt 字符串查找算法,簡(jiǎn)稱為 KMP算法,常用于在一個(gè)文本串 S 內(nèi)查找一個(gè)模式串 P 的出現(xiàn)位置。
這個(gè)算法由 Donald Knuth、Vaughan Pratt、James H. Morris 三人于 1977 年聯(lián)合發(fā)表,故取這 3 人的姓氏命名此算法。
是不是感覺(jué) Donald Knuth 這個(gè)名字很眼熟?沒(méi)錯(cuò),在前面 這或許是講解 Knuth 洗牌算法最好的文章 一文中也出現(xiàn)了他!
下面直接給出 KMP算法 的操作流程:
- 假設(shè)現(xiàn)在文本串 S 匹配到 i 位置,模式串 P 匹配到 j 位置
- 如果 j = -1,或者當(dāng)前字符匹配成功(即 S[i] == P[j] ),都令 i++,j++,繼續(xù)匹配下一個(gè)字符;
如果 j != -1,且當(dāng)前字符匹配失敗(即 S[i] != P[j] ),則令 i 不變,j = next[j]。此舉意味著失配時(shí),模式串 P相對(duì)于文本串 S 向右移動(dòng)了 j - next [j] 位 - 換言之,將模式串 P 失配位置的 next 數(shù)組的值對(duì)應(yīng)的模式串 P 的索引位置移動(dòng)到失配處
看不明白?直接看動(dòng)畫!
運(yùn)行過(guò)程
以下圖文本串 S 與模式串 P 為例:
首先,列出模式串 P 的所有子串:
| a | b | ? | ? | ? | ? | ? | ? |
| a | b | a | ? | ? | ? | ? | ? |
| a | b | a | a | ? | ? | ? | ? |
| a | b | a | a | b | ? | ? | ? |
| a | b | a | a | b | c | ? | ? |
| a | b | a | a | b | c | a | ? |
| a | b | a | a | b | c | a | c |
然后,求得每一個(gè)子串的所有前綴與后綴。
前綴 指除了最后一個(gè)字符以外,一個(gè)字符串的全部頭部組合;后綴 指除了第一個(gè)字符以外,一個(gè)字符串的全部尾部組合。
以第五列為例進(jìn)行演示。
前綴為
| a | b | ? | ? |
| a | b | a | ? |
| a | b | a | ? |
后綴為
| a | b | ? | ? |
| a | A | b | ? |
| b | a | a | b |
因此,它的前綴后綴的公共元素的最大長(zhǎng)度為 2。
求得原模式串 P 的子串對(duì)應(yīng)的各個(gè)前綴后綴的公共元素的 最大長(zhǎng)度表 下圖。
根據(jù)最大長(zhǎng)度表 去求 next 數(shù)組:next 數(shù)組相當(dāng)于“最大長(zhǎng)度值” 整體向右移動(dòng)一位,然后初始值賦為-1。
好了,獲取了 next 數(shù)組 后,KMP 算法 的操作就很清晰了。
將模式串 P 與文本串 S 的字母一個(gè)個(gè)進(jìn)行匹配,當(dāng)失配的時(shí)候,模式串向右移動(dòng)。
怎么移動(dòng)?
比如模式串的 b 與文本串的 c 失配了,找出失配處模式串的 next數(shù)組 里面對(duì)應(yīng)的值,這里為 0,然后將索引為 0 的位置移動(dòng)到失配處。
轉(zhuǎn)載于:https://www.cnblogs.com/fivestudy/p/11287725.html
總結(jié)
以上是生活随笔為你收集整理的七分钟理解什么是 KMP 算法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 不要错过路边的的风景
- 下一篇: [转]OpenCL 教学(一)