看到好多帖子讲KMP,这篇文章的图片最醒目,在这里我也记录一下自己的学习心得
字符串的匹配,首先需要一个字符串T,另一个是P,叫P其实就是模式的意思,用P来匹配T,如果用朴素的算法,就是一个字符一个字符来比较了,这就不说了,这个算法最大的问题在哪里,我举一个栗子,对于ab aba ,如果用ababe来对比的话,朴素的怎么对比呢,在abab肯定能对上,如图1,到了下一个就对不上了,那么接着呢。。。。向后移动一位,如图2
这个匹配的过程中有一个重要的信息被遗漏了,对于字符串T,由于比较长,我们可以认为这个字符串的字符在比较之前都是未知的,而这个P确是一定的,我们看到这个abab这前四个时,可以看出来,如果第一次不匹配时,可以向后移动2个字符,那么这两个ab就对上了,如图3
那么怎么能够了解这个信息呢,我们可以对P进行一个预处理,如果匹配到了P的第i-1个字符,即第i个字符不一样,那么让他直接向后移动next[i]位,就行了,现在主要的工作就是求这个数组,这是kmp算法的核心:
对于数组ababc而言,如果第i-1个元素对上了,第i个元素没有对上,先简单的看一下:
1 第一个a就没对上,那么向后移动一位,和b比较(这个T可能是baba....)
2 第一个a对上了,b没对上,向后移动一位
。。。
怎么求这个next数组呢,对于字符串P而言,当其匹配了前i-1个元素时,对第i个元素不匹配时,如何找下一个应该要对比的地方呢,就是找P(i)的后缀和P的前缀的共同部分:这里注意找的是最大的公共部分,如同图4
那么如何找这个前缀和后缀的共同部分呢,先考虑最极端的情况,这个P(i)和P没有公共部分,那么下一个要对比的地方就是0,即对P(i)和P的第一个元素对比,