KMP演算法總結

2022-07-27 03:15:13 字數 1674 閱讀 1542

其實kmp演算法與bf演算法的區別就在於kmp演算法巧妙的消除了指標i的回溯問題,只需確定下次匹配j的位置即可,使得問題的複雜度由o(mn)下降到o(m+n)。

在kmp演算法中,為了確定在匹配不成功時,下次匹配時j的位置,引入了next陣列,next[j]的值表示p[0...j-1]中最長字尾的長度等於相同字串行的字首。

假設主串:s: 『s(1)  s(2)  s(3) ……s(n)』 ;  

模式串 :p: 『p(1)  p(2)  p(3)…..p(m)』

繼續現在我們假設 主串第i個字元與模式串的第j(j<=m)個字元「失配」後,主串第i個字元與模式串的第k(k此時,s(i)≠p(j),  有

主串:               s(1)……  s(i-j+1)…… s(i-1)   s(i) ………….

|| (相配)   ||       ≠(失配)

匹配串:                        p(1) …….  p(j-1)   p(j) 

由此,我們得到關係式

『p(1)  p(2)  p(3)…..p(j-1)』   =    』 s(i-j+1)……s(i-1)』

由於s(i)≠p(j),接下來s(i)將與p(k)繼續比較,則模式串中的前(k-1)個字元的子串必須滿足下列關係式,並且不可能存在  k』>k  滿足下列關係式:(k即:

主串:        s(1)……s(i-k +1) s(i-k +2) ……s(i-1)     s(i) ………….

|| (相配)  ||           ||       ?(有待比較)

匹配串:                p(1)      p(2)    …… p(k-1)    p(k)

現在我們把前面總結的關係綜合一下

有:s(1)…s(i-j +1)…  s(i-k +1) s(i-k +2)  ……    s(i-1)     s(i) ……

|| (相配)  ||         ||               ||         ≠(失配)

p(1) ……p(j-k+1)   p(j-k+2)  …....   p(j-1)    p(j) 

|| (相配)  ||               ||          ?(有待比較)

p(1)       p(2)    …….    p(k-1)      p(k)

由上,我們得到關係:

『p(1)  p(2)  p(3)…..p(k-1)』   =     ' p(j-k+1) p(j-k+2) p(j-k+3)……p(j-1)』

這樣歸結到了求next函式。

下面是next函式方法:

1

void getnext(char* t, int* next)

2 15

else

16

19 }

20 }

當乙個字串以0為起始下標時,next[i]可以描述為"不為自身的最大首尾重複子串長度"。

也就是說,從模式串t[0...i-1]的第乙個字元開始擷取一段長度為m(m < i-1)子串,再擷取模式串t[0...i-1]的最後m個字元作為子串,如果這兩個子串相等,則該串就是乙個首尾重複子串。我們的目的就是要找出這個最大的m值。

詳細例項見朱站立版《資料結構》例4-5。

KMP演算法總結

kmp題目重在理解next陣列的含義 next陣列的作用 next j 記錄模式串中第 j 個字元的最長公共字首長度 重要,這是它的意義所在 第二種理解方式,當模式串與主串失配時,跳回的位置。next len 即字串 0 結束標誌的next值 單個字串匹配時與週期有關 hdu 1711 模板題 33...

KMP演算法總結

kmp演算法是用來實現模式匹配的,其時間複雜度是o m n 具體原理見 其中有用到next陣列來計算子串中公共項的位數,簡單來說,就是子串遇到不匹配時,就查next資料來決定前進幾位 移動位數 已匹配的字元數 對應的部分匹配值 1 要不要減一看next陣列第一位是不是為1,個人覺得加一後是有好處的,...

KMP演算法總結

現在假設有兩個字串a bbc abcdab abcdabde,b abcdabd。現在要在a中找b。比較暴力的方法是直接搜尋 void gosearch 上述 最核心就是while迴圈,舉兩個例子說明其作用 還是選取b串作為說明。假設現在要求next 6 那麼當前的j next 5 1 next陣列...