KMP原理

今天把kmp的原理回顾了一下,于是做一下总结

感谢该作者给出详尽的解释http://www.cnblogs.com/yjiyjige/p/3263858.html

简单阐明一下原理

KMP在寻找字符串匹配的过程中 保持主串的指针不动  每次匹配不成功  只对模式串进行处理

接下来我们自己来发现j的移动规律:

 

如图:C和D不匹配了,我们要把j移动到哪?显然是第1位。为什么?因为前面有一个A相同啊:

 

如下图也是一样的情况:

 

可以把j指针移动到第2位,因为前面有两个字母是一样的:

 

至此我们可以大概看出一点端倪,当匹配失败时,j要移动的下一个位置k。存在着这样的性质:最前面的k个字符和j之前的最后k个字符是一样的

如果用数学公式来表示是这样的

P[0 ~ k-1] == P[j-k ~ j-1]

这个相当重要,如果觉得不好记的话,可以通过下图来理解:

 

弄明白了这个就应该可能明白为什么可以直接将j移动到k位置了。

因为:

当T[i] != P[j]时

有T[i-j ~ i-1] == P[0 ~ j-1]

由P[0 ~ k-1] == P[j-k ~ j-1]

必然:T[i-k ~ i-1] == P[0 ~ k-1]

公式很无聊,能看明白就行了,不需要记住。

这一段只是为了证明我们为什么可以直接将j移动到k而无须再比较前面的k个字符。

好,接下来就是重点了,怎么求这个(这些)k呢?因为在P的每一个位置都可能发生不匹配,也就是说我们要计算每一个位置j对应的k,所以用一个数组next来保存,next[j] = k,表示当T[i] != P[j]时,j指针的下一个位置。

以上文章摘自该博文

对于模式串求next数组  便能够每次只进行模式串指针的移动

对于next的求解过程

next[0] = -1  next[1] = 0;

当str[j] == str[k] 时  next[j + 1] = next[j] + 1;

当不相等时  我们让k指针往前蹦  蹦到头或者相等为止

这样做的目的就是尽可能的使其能够与主串j之前的更多的字母匹配

然后kmp部分  就好说了   每次i不动  只移动j指针就好了

原文地址:https://www.cnblogs.com/zhanzhao/p/4760916.html