1. 程式人生 > >KMP演算法next陣列計算的理解——菜鳥福音

KMP演算法next陣列計算的理解——菜鳥福音

我的文章莫名找不到了。。。還是再寫一遍吧,希望對了解KMP的演算法有點幫助……

首先寫幾點
1)本文討論的KMP主要是嚴蔚敏的《資料結構》中第四章提到的KMP,即帶NEXT[]輔助陣列的KMP演算法
2)本文主要是討論KMP演算法NEXT[]陣列的計算的理解,一些數學上不嚴謹的地方還請見諒
3)本文主要針對演算法及資料結構的新手,希望能幫助大家快速理解KMP

KMP演算法在網路到處都是討論,在這裡假設我們都知道KMP演算法的基本原理,以及NEXT[]陣列的定義。

於是有
<定義1>
對於一個模式串P[],有相應的NEXT[]。對於每個P[K+1]有NEXT[K+1]=X,此時
‘P[1]P[2]..P[X-1]’ = ‘…P[K]’


因為,NEXT的意義在於使得模式串P[]與目標串T[]匹配到P[K-1]與T[J-1]都成功時,在P[K]!=T[J]的情況下,模式串需要移動後與目標串比較的位置。

以及
<結論1>
對於任意一個模式串P[]及其NEXT[],必然有
NEXT[1]=0;NEXT[2]=1
因為,第一個字元不匹配,只能將模式串右移,而第二個字元不匹配,只能比較第一個字元。

所以,現在根據以上得出的定義和結論,結合這樣一個假設
<假設>
對於某個模式串P[]及其NEXT[],已知某個字元P[K]及其前面所有的NEXT[]對應的值。
基於結論1,顯然成立。不妨設此時P[K]=Y;

現在,我們在上述假設下,求NEXT[K+1]=X,X為未知量。

那麼根據<定義1>,顯然有
‘P[1]P[2]..P[X-1]’ = ‘…P[K]’
同時因為P[K]=Y,所以有
‘P[1]P[2]..P[Y-1]’ = ‘…P[K-1]’

實際上,由KMP的NEXT[]本身有“滿足最大前後綴匹配”的原則(這個地方在理解上可以忽略,數學上也是可以證明的,本文就不證明了……),因此,

如果,P[Y]=P[NEXT[K]]=P[K],那麼有
‘P[1]P[2]..P[Y-1]P[Y]’ = ‘…P[K-1]P[K]’
而上面已經提到
‘P[1]P[2]..P[X-1]’ = ‘…P[K]’
“滿足最大前後綴匹配”

的性質,可以充要的推匯出:
X-1=Y。
即當P[NEXT[K]]=P[K]時,NEXT[K+1]=NEXT[K]+1。

如果,P[Y]!=P[K],那麼,設NEXT[Y]=Y2,(顯然Y2 < Y),因為<性質1>
‘P[1]P[2]..P[Y2-1]’ = ‘…P[K-1]’
以及KMP的性質,則回到迭代求解的過程中。

由此就可以理解KMP演算法中NEXT的求解了,希望能幫到更多人。
歡迎指正、討論!

謝謝閱讀!