KMP算法相对于BF算法,是控制了主串的回溯,只有子串回溯,并且子串每次会回溯到想要的位置,而不是回溯到子串的第一个字符处。关于next数组的生成,不解。数据结构书里面是这样写的:
void get_next(String T, int *next){
int i,j;
i = 1;
j = 0;
next[1] = 0;
while (i < T[0]) //这里T【0】存放的是串长度
if (j == 0 || T[i] == T[j]){ //T[i]总是表示后缀的单个字符 T[j]表示前缀的单个字符
++i;
++j;
next[i] = j;
}
else{
j = next[j]; //若字符不相同,则j值回溯
}
}
=============================================================
首先要理解,next数组元素值得意义是什么?我是这么理解的,next[i]的意义就是,当前字符之前的最大重复字串(前缀)的下一个字符的位置,比如串“ababc”,我们下标从1开始,next[5] = 3,当前字符为c时,他的前串最大重复的字符为ab,那么next[5] = 3,位于3位置的字符是ab之后的a。其目的就是j回溯的时候,从ab 之后的a开始比较,因为ab和后缀是重复的,既然之前比较的还是比较到了字符c,也就是说前缀ab也不用比较了,肯定相等。
那么对于计算next元素值的时候,上面的T[i],T[j] 我理解为是T[i]总是后缀字符串的最后一个字符,而T[j]总是前缀字符串的最后一个字符,为啥是最后一个呢,迭代呀,后面的利用前面的重复关系,前面我们说了,next元素值是当前字符之前的最大重复字串(前缀)的下一个字符的位置,也就是T[j]的下一个位置,即++j。也就是上面代码的if条件。那么如果if条件不满足,前面我们也说了,字符是迭代的,后面的继承前已经确定的next元素值,或者说重复关系,如果当前if条件不满足,则j要回溯到上一次重复串的下一个位置,开始重新匹配,迭代。