求nextval數組值有兩種方法,一種是不依賴next數組值直接用觀察法求得,一種方法是根據next數組值進行推理,兩種方法均可使用,視更喜歡哪種方法而定。
本文主要分析nextval數組值的第二種方法
a b a a b c a c 模式值
0 1 1 2 2 3 1 2 next數組
0 1 0 2 1 3 0 2 nextval數組
1.第一位的nextval值必定為0,第二位如果於第一位相同則取相同值下的next值為0,如果不同則取當下next的值為1。
2.第三位的next值為1,那么將第三位和第一位進行比較,均為a,相同,則,第三位的nextval值為0。
3.第四位的next值為2,那么將第四位和第二位進行比較,不同,則第四位的nextval值為其next值,為2。
4.第五位的next值為2,那么將第五位和第二位進行比較,相同,第二位的next值為1,則繼續將第二位與第一位進行比較,不同,則第五位的nextval值為第二位的next值,為1。
5.第六位的next值為3,那么將第六位和第三位進行比較,不同,則第六位的nextval值為其next值,為3。
6.第七位的next值為1,那么將第七位和第一位進行比較,相同,則第七位的nextval值為0。
7.第八位的next值為2,那么將第八位和第二位進行比較,不同,則第八位的nextval值為其next值,為2。
三、next和nextval比較
Next數組的缺陷舉例如下:
比如主串是“aab…..” 省略號代表后面還有字符。
模式串“aac”
通過計算aac的next數組為012(另外,任何字符串的第二位字符的next總是1,因此你可以認為他固定為1)
當模式串在字符c上失配時,會跳到第2個字符,然后再和主串當前失配的字符重新比較,即此處用模式串的第二個a和主串的b比較
即 aab aac
顯然a也不等於b。然后 會跳到1,接着比,然后又失配,直到最后才使主串后移一位。
而“aac”的nextval數組為002 當在c失配時會跳到2,若還失配就直接跳到0,比next數組少比較了1次。
在如果模式串很長的話,那可以省去很多比較,因此你應該使用nextval數組。
四、嚴蔚敏
上:http://v.youku.com/v_show/id_XODYxNjExODQ=.html 第 34分鍾開始
下:http://www.56.com/u28/v_NjAwMzA0ODA.html
五、代碼實現:
public static void main(String [] args) throws IOException{//main函數,輸入主串和模式串
System.out.print("請輸入主串:");
Scanner sn1 = new Scanner(System.in);
String s1 = sn1.next();
System.out.print("請輸入模式串:");
Scanner sn2 = new Scanner(System.in);
String s2 = sn2.next();
char [] s3 = s1.toCharArray();
char [] s4 = s2.toCharArray();
System.out.print(KMP_test(s3,s4));
}
public static int KMP_test(char [] s, char [] t){// 主串順序匹配
int [] next = next(t);
int i = 0, j = 0;
while(i
if(j == -1 || s[i] == t[j]){
++i;
++j;
}else{
j = next[j];
}
}
System.out.println(i);
if(j
return 0;
}else{
return i-t.length;
}
}
public static int [] next(char [] t){// next函數求解
int i = 0, j = -1;
int [] next = new int[t.length];
next[0] = -1;
while(i
if(j == -1 || t[i] == t[j]){
++i;
++j;
next[i] = j;
}
else
j = next[j];
}
System.out.println(Arrays.toString(next));
return next;
}
對於改進的KMP算法,只需要把next函數換為nextval函數就行了
public static int [] next(char [] t){
int i = 0, j = -1;
int [] next = new int[t.length];
next[0] = -1;
while(i
if(j == -1 || t[i] == t[j]){
++i;
++j;
if (t[i] != t[j]) {
next[i] = j;
} else {
next[i] = next[j];
}
}
else
j = next[j];
}
System.out.println(Arrays.toString(next));
return next;
}
