如何计算next数组:
- 计算子串的部分匹配值
- 如果规定next[1] = -1,则将部分匹配值全部右移一位,左补-1
- 如果规定next[1] = 0,则将部分匹配值全部右移一位,左补-1的基础上,再全部加1
如果规定next[1] = 0,则next[j]数组的意义:在子串的第j个字符与主串发生失配时,则跳到子串的next[j]位置重新与主串当前位置进行比较。
void get_next(String T, int next[]) {
int i = 1, j = 0;
next[1] = 0;
while (i < T.length) {
if (j == 0 || T.ch[i] == T.ch[j]) {
++i; ++j;
next[i] = j; // 若pi = pj,则next[j+1]=next[j]+1
} else {
j = next[j]; // 否则令j=next[j]
}
}
}
int Index_KMP(String S, String T, int next[]) {
int i = 1, j = 1;
while (i <= S.length && j <= T.length) {
if (j == 0 || S.ch[i] == T.ch[j]) {
++i; ++j; // 继续比较后继字符
} else {
j = next[j]; // 模式串向右移动
}
}
if (j > T.length) {
return i-T.length; // 匹配成功
} else {
return 0;
}
}
KMP算法改进—nextval数组
当子串为aaaab,主串为aaabaaaab,在第4个元素失配,此时子串回退,但回退的后的元素必定还是失配的,所以对此进行改进,优化next数组。
如果 p j = p n e x t [ j ] p_j = p_{next[j]} pj=pnext[j],那么回退到 p n e x t [ j ] p_{next[j]} pnext[j]必然失配,此时将 n e x t [ j ] next[j] next[j]修正为 n e x t [ n e x t [ j ] ] next[next[j]] next[next[j]],直到两者不相等为止,更新后的数组命名为nextval
void get_nextval(String T, int nextval[]) {
int i = 1, j = 0;
nextval[1] = 0;
while (i < T.length) {
if (j == 0 || T.ch[i] == T.ch[j]) {
++i; ++j;
if (T.ch[i] != T.ch[j]) nextval[i] = j;
else nextval[i] = nextval[j];
} else {
j = nextval[j];
}
}
}
nextval数组手算过程