kmp演算法是在模式串的next陣列基礎上進行的,如何求解next陣列就成了關鍵。
next陣列的求解和主串無關,只與模式串自身相關。
則next[j]=
-1, 當j=0時
max {k|00,其他情況
比如對於p[5]=c, next[5]=2,因為'p0p1'='p3p4',此時k=2。
下面參考《資料結構》嚴蔚敏書中的方法,介紹求解next陣列的遞推方法。
根據上述定義,next[0]=-1.
設next[j]=k,則根據定義有下列關係式成立:
'p0,...,pk-1' = 'pj-k,...,pj-1'
其中k為滿足0那麼next[j+1]=?
(1)如果pk = pj,即p[j]=p[next[j]] 則表明:
'p0,...,pk-1,pk' = 'pj-k,...,pj-1,pj'
則next[j+1]=next[j]+1.
比如考慮模式串p=abcabcabd,(假設陣列下標從0開始),假設已經求得next[0~4],現在要求next[5]。
p a b c a b c
a b d
next -1 0 0 0 1
j 0 1 2 3 4 5 6 7 8
那麼next[5]=next[4]+1=2。因為p[j]=p[next[4]]=p[k].此時的j=4,k=next[j]=1.
(2)如果pk != pj,即p[j] != p[next[j]],則表明:
'p0,...,pk-1,pk' = 'pj-k,...,pj-1,pj'
但有'p0,...,pk-1' = 'pj-k,...,pj-1'
此時可以把求解next陣列看成是乙個模式匹配的問題,整個模式串即是主串又是模式串。
根據'p0,...,pk-1' = 'pj-k,...,pj-1',在pk和pj處遇到了不想等的情況,此時應當模式串「向右滑動至以模式串中的第next[k]個字元和主串中的第j個字元相比較(主串不回溯)」。若next[k]=k',且pj = pk',則說明主串中第j+1個字元之前存在乙個長度為k'(代替情況(1)中的k)的最長字串,和模式串中從首字元其長度為k'的字串相等,即:
'0,...,pk-1,pk' ' = 'pj-k,...,pj-1,pj' (這裡和情況(1)相比,用k'代替了k)
這就是說,next[j+1]=k'+1=next[k]+1.
同理,如果pj != pk',則應該將模式串繼續向右滑動,直至將模式串中第next[k']個字串和pj對齊。......以此類推,直至pj和模式串中的某個字元匹配成功或者不存在任何k'滿足 '0,...,pk-1,pk' ' = 'pj-k,...,pj-1,pj' ,此時next[j+1] = 0.
比如考慮p=abaabcac,已知求得next[0~5],現在要求next[6].
p a b a a b c a c
next -1 0 0 1 1 2
j 0 1 2 3 4 5 6 7
現在要求next[6],因為next[5]=2,又p2 != p5,則需要繼續比較p5 和p[next[2]]即比較p5和p0,這相當於向右滑動模式串;又p5 != p0,且next[0]=-1,所以next[6]=0.
KMP演算法Next陣列求解
相信對於kmp演算法本身大家都理解,最難理解的就是這個next陣列的求解了。這是 p 為模式串,下標從 0 開始 void getnext string p,int next else j next j 根據我的理解,i 和 j 可以看成是兩個指標,用來跟蹤當前匹配的位置。可以發現 i 是會不斷的往...
KMP演算法 next陣列的求解
void getnext vector int next,string s if s i s j next i j 為什麼j按照上述的更新方法,是s 0 i 這個字串中字首和字尾相等的最大字串的長度 j的更新方式 如果s i s j j一直回退 j next j 1 直到回退到s j s i 如果s...
KMP演算法 快速求解next陣列
在kmp演算法中,最關鍵的就是求解next陣列了。那麼如何快速求解next陣列呢?已知模式串 ab cdabdd a 其next陣列 00 0 0 12 0 0 1 那麼是如何求證出來的呢?首先字串從左至右遍歷。第乙個字元a的next陣列對應元素為0,第乙個字元a和第2個字元b比,不相等。b 0 表...