个人心得:
刚学数据结构,遇到kmp感觉有点难度,费了几个小时弄懂了大概。
首先我们来看
这是第一位不匹配的状态:图1
主串移到下一位,模式串不变
第二位不匹配的情况:图2
主串不变,模式串回溯到第一位
第三位不匹配的情况:图3
主串不变,模式串回溯到第二位
第四位不匹配的情况:图4
主串不变,模式串回溯到第三位
可以观察到,除了第一位不匹配的时候需要移动主串,其余位不匹配都只移动模式串。
那么怎样知道回溯到第几位呢?
首先我们看图3:
模式串箭头左边的公共前后缀是“a”,长度(记为L)是1
再看图4:
模式串箭头左边的公共前后缀是“aa”,长度(记为L)是2
我们可以注意到二者下一次匹配的箭头左边的长度就是L,而匹配的就是第(L+1)位。
箭头左边的看似我们没有匹配就跳过了,实际上它就是公共前后缀,事实已经匹配。
那么当没有公共前后缀或者说公共前后缀就是箭头左边的一整个字串,该怎么办呢?
看图5:
也是跟我们上面说的一样,并且等同于图2:
我自己看的时候一直看不出第一位和第二位不匹配有什么区别,现在终于知道了:第一位不匹配移动主串,第二位不匹配移动模式串。
到这我们也可以发现其实移动多少跟主串没半毛钱关系。直接上模式串!
KMP算法的改进:
当 AAABAAAAB
与 AAAA
匹配
第一次:
AAABAAAAB
AAAA
第二次:
AAABAAAAB
AAAA
第三次:
AAABAAAAB
AAAA
第四次:
AAABAAAAB
AAAA
看起来挺呆。要是我们一开始就知道这样就好了!因此我们需要比较当前模式串不匹配的字母是否与下一个待匹配的字母相同,如果相同就跳过继续寻找下一个待匹配的字母,直至与该字母不相同。
就比如这种情况:
当“B”匹配失败时候就不必进行第一步了,直接一步到位进行第二步!
以上就是我的一些理解。没有具体的代码和算法,仅供理解过程。