資料結構 關於KMP演算法中next函式的詳細解析

2021-06-29 05:50:59 字數 2200 閱讀 8217

之前看到資料結構中字串的模式匹配時,花了半天的時間,才把kmp演算法中的next函式整明白了,結果過了幾天在看到這時,只記得next[j+1]=next[j]+1,可是有時候能套公式正確算出,有時候就算不對,所以今天再重新理一遍思路,順便記錄下來,防止哪天腦子再短路了,又不知道怎麼求解的了。

先看看next資料值的求解方法

位序       1   2   3   4   5   6   7   8   9   

模式串     a   b   a   a   b   c   a   b   c   

next值     0   1   1   2   2   3   1   2   3   

next陣列的求解方法是:

1.第一位的next值為0

2.第二位的next值為1

後面求解每一位的next值時,根據前一位進行比較

3.第三位的next值:第二位的模式串為b ,對應的next值為1;將第二位的模式串b與第一位的模式串a進行比較,不相等;則第三位的next值為1(其他情況均為1)

4.第四位的next值:第三位的模式串為a ,對應的next值為1;將第三位的模式串a與第一位的模式串a進行比較,相同,則第四位的next值得為1+1=2

5.第五位的next值:第四位的模式串為a,對應的next值為2;將第四位的模式串a與第二位的模式串b進行比較,不相等;第二位的b對應的next值為1,則將第四位的模式串a與第一位的模式串a進行比較,相同,則第五位的next的值為1+1=2

6.第六位的next值:第五位的模式串為b,對應的next值為2;將第五位的模式串b與第二位的模式中b進行比較,相同,則第六位的next值為2+1=3

7.第七位的next值:第六位的模式串為c,對應的next值為3;將第六位的模式串c與第三位的模式串a進行比較,不相等;第三位的a對應的next值為1,

則將第六位的模式串c與第一位的模式串a進行比較,不相同,則第七位的next值為1(其他情況)

8.第八位的next值:第七位的模式串為a,對應的next值為1;將第七位的模式串a與第一位的模式串a進行比較,相同,則第八位的next值為1+1=2

9.第八位的next值:第八位的模式串為b,對應的next值為2;將第八位的模式串b與第二位的模式串b進行比較,相同,則第九位的next值為2+1=3

如果位數更多,依次類推

kmp演算法的關鍵在於求算next陣列的值,即求算模式串每個位置處的最長字尾與字首相同的長度,下面按照遞推的思想總結一下求解next陣列:

根據定義next[1]=0,假設next[j]=k, 即p[1...k-1]==p[j-k,j-1]

1)若p[j]==p[k],則有p[1..k]==p[j-k,j],很顯然,如果next[j]=k; 則next[j+1]=next[j]+1=k+1;否則

next[j+1]=k+1!=next[j]+1;(當初就想著記公式簡單可以直接套用呢,結果只記住next[j+1]=next[j]+1以至於後來迷糊了)

2)若p[j]!=p[k],則可以把其看做模式匹配的問題,即匹配失敗的時候,k值如何移動,顯然k=next[k]。

因此可以這樣去實現:

void getnext(char *p,int *next)

{ int j,k;

next[1]=0;

j=1;

k=0;

while(j

kmp模式匹配演算法改進:

後來有人發現其實kmp演算法還是有缺陷的,比如主串s=「aaaabcde」,子串t=「aaaaag」,其next陣列為012345;當i=5 ,j=5是「b」與「a」不匹配,此時j=next[5]=4,又發現j=4時,「b」與「a」不匹配,依次類推,直到j=next[1]=0;此時i++,j++,i=6,j=1從而我們發現中間有多餘的判斷,由於子串t中第2、3、4、5位置的字元都與首位的「a」相同,即可以用首位next[1]的值去取代與它字元相等的後續next[j]的值,即next陣列改為000005,此時由i=5,j=5時「b」與「a」不匹配,此時j=next[5]=0;此時i++,j++得到i=6,j=1,即可省去中間的多餘判斷。因此我們需要改進next函式的求解方法。

/* 求模式串t的next函式修正值並存入陣列nextval */

void get_nextval(string t, int *nextval)

{ int i,j;

i=1;

j=0;

nextval[1]=0;

while (i

資料結構 KMP演算法

求串的模式值next n 定義 1 next 0 1 意義 任何串的第乙個字元的模式值規定為 1。2 next j 1 意義 模式串t中下標為j的字元,如果與首字元相同,且 j的前面的 1 k個字元與開頭的 1 k個字元不等 或者相等但t k t j 1 k 如 t abcabcad 則next 6...

資料結構 KMP演算法

在我的理解,kmp演算法最核心的同時最難理解的是這個next 函式。但是,next 的值是挺好求的,難在哪呢?這個函式難在邏輯。理解起來很費勁,但真的很好用,並且這個函式的結果很好求。例如求模式串t ababaaa 的next j 的函式值 是這樣的,當j 0,next 0 1,對於任何子串,第乙個...

資料結構 KMP演算法

要完善乙個string字串類,那麼實現查詢子串的功能是必不可少的,實現子串查詢可以使用樸素演算法,每次匹配乙個字元後向右移動乙個位置,這樣執行下來效率是比較低的,所以就有了kmp演算法,它能夠準確的知道當前字元不匹配後字串應該向右移動多少位,由於剛接觸kmp演算法,所以很多還明白的不是很透徹,在此記...