KMP演算法的next陣列是怎麼算的

2021-10-04 05:35:37 字數 2177 閱讀 8615

首先我們來看看 「部分匹配表(next)」 是怎麼產生的。

先介紹字首,字尾是什麼

對於乙個字串來說,如單詞「spark」來說:

字串:spark

字首:s,sp,spa,spar

字尾:park,ark,rk,k

「部分匹配值」就是「字首」和「字尾」的最長的共有元素的長度。以「ababcabaa」為例:

「a」的字首和字尾都為空寂,共有元素的長度為0;

「ab」的字首為[a],字尾為[b],共有元素的長度為0;

「aba」的字首為[a,ab],字尾為[ba,a],共有元素的長度為1;

「abab」的字首為[a,ab,aba],字尾為[bab,ab,b],共有元素的長度為2;

「ababc」的字首為[a,ab,aba,abab],字尾為[babc,abc,bc,c],共有元素的長度為0;

「ababca」的字首為[a,ab,aba,abab,ababc],字尾為[babca,abca,bca,ca,a],共有元素的長度為1;

「ababcab」的字首為[a,ab,aba,abab,ababc,ababca],字尾為[babcab,abcab,bcab,cab,ab,b],共有元素的長度為2;

「ababcaba」的字首為[a,ab,aba,abab,ababc,ababca,ababcab],字尾為[babcaba,abcaba,bcaba,caba,aba,b,a],共有元素的長度為3;

「ababcabaa」的字首為[a,ab,aba,abab,ababc,ababca,ababcab,ababcaba],字尾為[babcabaa,abcabaa,bcabaa,cabaa,abaa,ba,aa,a],共有元素的長度為1;

由此可見,「ababcabaa」的next陣列為[0,0,1,2,0,1,2,3,1]。當然,這是我們人眼觀察的結果,但是程式怎麼寫呢?先來看一張圖:

如圖所示, 假設字串為char型陣列t,部分匹配值為next陣列。我門以第9個元素也就是t[8]的時候為例。

我們先宣告乙個變數j,我們知道,當j為(0,1,2),i為(5,6,7)的時候,一直是相等的,然後i++到8,j++到3之後,就不相等了。我剛開始的想法就是,只要不相等,置為0就可以了,但從上圖來看,明顯i=8的時候,對應的值為1,所以沒有那麼簡單。

我們可以先看下當前j值為3時的前乙個也就是next[ j-1 ](next[2])的值,此圖中為1,則說明一定是t[0] == t[2]。然而我們既然比較到了t[3]和t[8],說明一定t[2] == t[7],那由此可見當next[2]為1的時候,t[0] == t[7],所以我們應該比較的是t[1]是否等於t[8]。為以下幾種:

當t[1] == t[8] 時,return值為2;

當t[1] != t[8] 時,比較t[0] ?= t[8];

如果t[0] == t[8],return值為1,否則return值為0。

我們再來舉個例子,如果next[j - 1] == 2,那麼說明陣列t的前兩個元素t[0],t[1]分別與t[j-2]和t[j-1]相等,相同的我們比較到了j和i的位置,說明t[j-2] == t[i-2] 且 t[j-1] == t[i-1]。由此得出t[0] == t[i-2],t[1] == t[i-1],那我們首先要比較的就是t[2]和t[i]是否相等,如果相等返回3,如果不相等繼續比較t[0]和t[i],如果相等返回1,否則返回0。

我們可以用公式 j = next[j-1] 來設定j,如圖中,當j==3和i==8的時候,不相等,如上分析的那樣我們會去找j==3的前乙個元素對應的next的值,如果next[j-1] == 1,則比較第2個元素t[1],此時恰好為t[ next[j-1] ],因此要把next[j-1]賦值給j,然後迴圈,直到j的值為0。

如果還是一知半解,帶入next[j-1] == 2的例子試試就好了。

附上此處**:

public static int kmpnext(string dest)

if (dest.charat(i) == dest.charat(j))

}return next;

}

KMP演算法中怎麼求next陣列

例如 1 2 3 4 5 6 7 8 模式串 a b a a b c a c next值 0 1 1 2 2 3 1 2 next陣列的求解方法是 第一位的next值為0,第二位的next值為1,後面求解每一位的next值時,根據前一位進行比較。首先將前一位與其next值對應的內容進行比較,如果相等...

KMP演算法 next陣列

通過上文完全可以對kmp演算法的原理有個清晰的了解,那麼下一步就是程式設計實現了,其中最重要的就是如何根據待匹配的模版字串求出對應每一位的最大相同前字尾的長度。我先給出我的 1 void makenext const char p,int next 214 next q k 15 16 現在我著重講...

KMP演算法 NEXT陣列

kmp和next陣列基本上是一起用的,有了next陣列,才有kmp演算法,講道理來說這兩個都是基於最大前字尾和,也就是說需要用到kmp的時候必須先把next陣列先求出來,next陣列就是由所匹配的word的每個子串的前字尾和最大匹配得到的,說實話next陣列的演算法給優化得已經很無解了,以至於至今我...