1. 程式人生 > >對KMP算法通過代碼生成next數組理解

對KMP算法通過代碼生成next數組理解

通過 [] get 下標 n-1 while 導致 代碼 如果

本文是根據考研數據結構2019版天勤高分筆記理解編寫的:

首先給出代碼:

1 void getnext(Str substr,int next[]){

 2     int i=0,j=0;
 3     next[1]<=0;
 4     while(i<substr.length){
 5        if(j==0 || substr.ch[i]==substr.ch[j]){      //倆種情況會導致j==0。a,給串第一個元素的next[1]賦值時j默認為0   b,當模式串和主串不匹配時,j回溯到next[1]=0
//當前元素和已經匹配的串(正在延伸的前綴)的下一個元素進行比較,相等就繼續延伸,否則j進行回溯,第10行(需要明白next的作用) 6 ++i;++j; 7 next[i]=j; //j表示0-j-1的前綴和後面一部分的子串已經匹配成功 8 } 9 else{ 10 j=next[j]; //j回溯 11 } 12 } 13 }

技術分享圖片

數組pre和數組p一致,即next[j]代表已匹配前綴串pre的下標 如:j=5就代表已匹配的前綴ADAB的下標1,2,3,4

j=5時,ch[11]!=ch[5],此時,退而其次,在已匹配的串"ADAB"中尋找能匹配D的元素。

next數組的作用就是當模式串中第j個字符發生不匹配時,應從next[j]處的字符開始重新與主串比較。所以j回溯的時候用的是j=next[j];

只是:為什麽next能起這樣的作用呢?給個串對照一下:

技術分享圖片

這裏我只把上面那部分的串的4位置和10位置的B改成了A,next數組只有next[5]由1變成了2.

現在講講我自己的理解:1,回退的過程中不僅2位置要和11位置想對應,2位置之前的所有位置(雖然這裏只有一個元素)都必須和11位置前的響應元素一一對應,而next數組就代表前面有多個字符和前綴匹配成功。

2,正如前面所說的,數組pre和數組p一致,即next[j]代表已匹配前綴串pre的下標 ,,為什麽改next【5】是2,對應了2(下標)位置的D,因為4位置的A和前綴A匹配。

=》保證倆個元素比較前,前綴和 j 位置前的對應長度的串是相等的(也就 是next的作用)

c和D不匹配ADAA這個前綴串的前綴是A,回溯到j=2,此時是保證了2(因為舉例較簡單,所以前綴只有一個元素,但我們可以把2位置發散成n位置)位置前所有的前綴(2-1 即n-1)個元素是和C元素前(2-1 即n-1)個元素匹配成功的;

而"ADAAC"和"ADAAD"中的"ADAA"的元素是匹配成功的,所以保證了ch【2-1】=ch【5-1】=ch【11-1】同樣,這裏的ch雖然只是一個字符,但也可以發散成一個串。

3,如果沒有符合要求的子串,j必定回溯到1.

小編也是花了一整天根據自己對書本的理解,如果大家有什麽不明白還請耐心點,kmp需要時間來理解!




對KMP算法通過代碼生成next數組理解