關於KMP的next函式的原理分析

2022-05-08 22:54:13 字數 2154 閱讀 9506

kmp是上學期學資料結構時候學的,當時就沒學太明白,後來又自己琢磨了幾次,但始終是一知半解。今天起床了又想起來kmp,以下是思考得到的一點東西。

首先學過kmp的都知道要寫兩個函式,乙個計算next陣列,乙個kmp主體函式,那麼next陣列裡存的到底是啥呢。首先答案是:next[i]存的是字串[0,i]的前字尾最長公共長度減1的值。下面先解釋下前字尾。

引用張別人的圖:

也就是說只有乙個元素時候前字尾都為空,即不能拿整個字串作為字首or字尾,注意這點即可。

我們把第i位對應的最大公共前字尾長度減1的值作為next[i]的值,這一點是為了之後計算的方便,後續會提到。

下面是next陣列的計算函式

//建立next陣列

int create_next(int* address,int len,string str)

if(str[k+1]==str[i])

address[i]=k;

}}

首先address[0]=-1,原因上面說了。每次for迴圈裡的i是代表字串的游標,每次for迴圈幹的事是計算出字串[0,i]的最長公共前字尾元素個數,當然我們可以乙個個數,先看str[0]=str[i]成立不成立,再看str[0]=str[i-1]&&str[1]=str[i]成立不成立,依次類推。但是這樣重複考察了太多元素,故我們採用簡便一點的方法,我畫了個圖。

如圖,前後黑括號代表[0,i-1]的最長公共前字尾,但str[k+1]!=str[i],那麼我們要找黑括號裡的更小的藍括號,讓前後藍括號相同。注意看圖,找到滿足上面條件藍括號的時候,左邊藍括號就在左邊黑括號的左端,右邊藍括號在右邊黑括號的右端,這不就是求[0,k]或者[i-1-k,i-1]的最長公共前字尾長度麼?再看下k=next[k],是不是這回懂為啥這麼寫了。從最開始的黑括號尋找藍括號的部分就是next函式第一部分,也就是下面這個while迴圈做的事情,想一想是不是

int k=address[i-1];

while(str[k+1]!=str[i]&&k>-1)

找到上面的一對藍括號之後,就出去while迴圈了,接下來是:
if(str[k+1]==str[i])

address[i]=k;

閒著沒事又敲了個python的:

def create_next(next_list,str):

str_len=len(str)

next_list.clear()

k=-1

for i in range(str_len):

while k!=-1 and str[k+1]!=str[i]:

k=next_list[k]

if str[k+1]==str[i]: #若k為-1也成立

k+=1

next_list=

def kmp(target,pattern):

#target目標串,pattern模式串

create_next(next_list,pattern)

tar_len=len(target)

pat_len=len(pattern)

k=-1

for i in range(tar_len):

while k!=-1 and target[i]!=pattern[k+1]:

k=next_list[k]

if target[i]==pattern[k+1]:

k+=1

if k==pat_len-1: #模式串全部匹配,即匹配成功

return i-pat_len+1

x="bacbababadababacmbabacaddababacasdsd"

y="ababaca"

print(kmp(x,y))

關於KMP的next陣列

明明寫的和課本一樣,但是在pta就是不正確,參考了別人的答案,發現有乙個地方不一樣記錄一下!include include include int next1 1000 next1 j k,表示當t i p j 時,j指標的下乙個位置。求字串在主串中第一次出現的位置 void get next1 c...

關於KMP演算法的next陣列

kmp的next陣列求法是很不容易搞清楚的一部分,也是最重要的一部分。我這篇文章就以我自己的感悟來慢慢推導一下吧!保證你看完過後是知其然,也知其所以然。如果你還不知道kmp是什麼,請先閱讀上面的鏈結,先搞懂kmp是要幹什麼。下面我們就來說說kmp的next陣列求法。kmp的next陣列簡單來說,假設...

KMP演算法中的next函式

kmp演算法詳解看 next i 表示當模式串t i 與主串失配時,模式串的索引回溯到next i 主串的索引不變 下面串的下標均從0開始 1 i 0 next i max k 0 k 證明模式串next函式的可行性 當t i 與 s j 失配時,即 t i s j 時 可得t 0.i 1 s j ...