nextval 數組(失敗函數)。i, j 掃描:i++, j++j = nextval[j](模式串右移)j == T.length 時匹配成功,返回起始下標。在 KMPIndex 函數的核心判斷處添加打印:
int KMPIndex(SqString s, SqString t) {
int nextval[MaxSize], i = 0, j = 0;
GetNextval(t, nextval);
int step = 0;
while (i < s.length && j < t.length) {
step++;
// 關鍵:輸出當前比較的字符、下標、nextval 值
printf("[Step %3d] i=%2d('%c') j=%2d('%c') nextval[j]=%2d\n",
step, i, s.data[i], j, t.data[j], nextval[j]);
if (j == -1 || s.data[i] == t.data[j]) {
i++; j++;
} else {
j = nextval[j];
}
}
if (j >= t.length) return i - t.length;
return -1;
}
[Step 1] i= 0('a') j= 0('a') nextval[j]=-1
[Step 2] i= 1('b') j= 1('b') nextval[j]= 0
[Step 3] i= 2('c') j= 2('c') nextval[j]= 0
[Step 4] i= 3('a') j= 3('a') nextval[j]= 0
[Step 5] i= 4('a') j= 4('b') nextval[j]= 0 // 失敗,j 回溯
[Step 6] i= 4('a') j= 0('a') nextval[j]=-1 // 繼續比較
...
匹配,從第 10 個數開始
同理在 GetNextval 中打印 j, k, t.data[j], t.data[k], nextval[j],觀察前綴表生成邏輯。
nextval 如何實現「模式串自我遷移」。