經典KMP演算法整理

2021-08-11 11:11:57 字數 1141 閱讀 1615

kmp演算法

大名鼎鼎的演算法

kmp由三位前輩的名字縮寫組成

其中第一位就是寫the art of the computer programming的高德納

它是一種效率很高的字串匹配演算法

傳統樸素做法的時間複雜度為o(n*m)

而kmp演算法能將時間複雜度縮小到o(n+m)

下面進入正題

kmp演算法

那麼究竟快在**呢?

我們回顧一下傳統做法

一旦匹配失敗後就從頭開始匹配

這樣很浪費時間

我們考慮讓模式串在主串上盡可能地向右滑動

可以跳過一些不必要的判斷

這個時候我們需要引入字首函式來讓模式串盡可能地向右移動

我們記主串為s,模式串為t,主串的下標為(1<=i<=n),模式串的下標為(1<=j<=m)

假設我們檢查到s[i]和t[j],結果發現它們不匹配

則我們知道從s[i-j+1]到s[i]與t[1]到t[j]完全匹配

那麼我們考慮i-j+1如果s(k,k+m-1)與模式串完全匹配,那麼必要條件是k>=i或者

重點來了

t(k,i-1)與t(1,i-k)相匹配,同時,t(k,i-1)還與t(k+i-j,j-1)相匹配

所以t(1,i-k)是t(1,j-1)的字尾

kmp演算法的核心就是:令pi[j-1] = max

然後將模式t向右滑動,使得索引指標指向si

和t的第pi[j-1] + 1個字元。pi[i]的大小與主串s並無關聯,所以我們應該事先通過預處理求出並儲存所有pi[i](1< i

pi[0]=-1;

for (i=1;i<=m;i++)

q=pi[i-1];

while (q>=0)and(t的第q+1個字元不等於第i個字元)  q=pi[q];

pi[i]=q+1;

有了字首函式

接下來的事就變得簡單起來了

我們需要做的就是不斷的滑動

嗯,就是這樣

q = 0

for (i=1;i<=n;i++)

while (q>0)&&(t[q]!=s[i])

q=pi[q];

if (t[q]==s[i]) {

q++;

if (q==m) then 匹配成功!

經典演算法 KMP演算法詳解

內容 1 問題引入 2 暴力求解方法 3 優化方法 4 kmp演算法 1 問題引入 原始問題 對於乙個字串 str 長度為n 和另乙個字串 match 長度為m 如果 match 是 str 的子串,請返回其在 str 第一次出現時的首字母下標,若 match 不是 str 的子串則返回 1 注 子...

經典的kmp演算法教程

字串匹配是計算機的基本任務之一。舉例來說,有乙個字串 bbc abcdab abcdabcdabde 我想知道,裡面是否包含另乙個字串 abcdabd 許多演算法可以完成這個任務,knuth morris pratt演算法 簡稱kmp 是最常用的之一。它以三個發明者命名,起頭的那個k就是著名科學家d...

KMP演算法經典講解

kmp演算法的思想都是一樣的,看了很多講解,基本上都只是在next陣列的表示上是有區別的,我覺得乙個很6的大神,講的很好 這位大神的next i 表示的是如果模板串p的第i位與母串s匹配失敗,則從模板串的哪個位置開始進行下一次比較。母串s和模板串p都是從0開始到len 1,next陣列也是從0開始,...