首先,非常推荐KMP的讲解看这一篇文章:如何更好地理解和掌握 KMP 算法?
理解了pmt之后,会有一个疑惑:为什么要把值都往后移动一位,并设index 为0 位置为-1?
我们来看一下这个版本的代码
int KMP(char * t, char * p)
{
int i = 0;
int j = 0;
while (i < strlen(t) && j < strlen(p)){
if (j == -1 || t[i] == p[j]){
i++;
j++;
} else j = next[j];
}
if (j == strlen(p))
return i - j;
else
return -1;
}
主要看一下这一句, 这边j是对应的是 next 的下标。
else j = next[j];
以这边为例,模式码abababca,匹配码abababd,在i 和 j 如图下标为6时,匹配失败
abababca
abababd
6
由于已经知道前缀后后缀有部分相同,那这部分就不用比了,例如这里6匹配失败,但是index5之前是匹配成功的,且value 为4,意味着匹配码里这个字符的前缀和后缀有四个数还是一样的,那么我们从匹配码第五个数处开始比较,而很巧啊!这边第五个数的下标就是4
,我们需要回溯匹配,都是通过的是那个数组如果只是pmt的话,代码需要写成,
else j = next[j-1];
于是往后移一位之后就可以写成j=next[j]的形式,且多出来的第一位,用于做标志位(标志位有判断是不是从头开始匹配的作用//TODO具体作用待补充)