参考文献:算法导论
实际匹配过程引用自:http://ds.fzu.edu.cn/fine/resources/FlashContent.asp?id=40
一般能想到
一个字符串比配问题,我们可能最长能想到的就是回溯的比较两个串,例如
abcacabababcb和ababc两个串进行比较
通常的做法是:
- 从第一个字符开始比较,abcacabababcb 和 ababc比较,发现相同
- abcacabababcb 和 ababc比较,发现相同
- abcacabababcb 和 ababc比较,发现不同
- 从第二个字符开始比较,abcacabababcb 和 ababc比较,发现不同
- 从第三个字符开始i比较
- ...
KMP算法
KMP和有限自动机一样,需要对模式串有预处理,但是KMP对模式串的预处理时间复杂度为O(m),而有限自动机的时间复杂度为O(m|∑|),显然KMP是一种更为高效的算法
和有限自动机一样,KMP也需要预先处理一个函数π,该函数的处理思想为设置一个变量来保存上一次匹配的最长前缀k,即表示到上一次字符串处理结束为止,模式串长度为k的前缀和其长度为k的后缀相同,也就是说这一次我们只要比较第k+1个字符和当前遍历到的字符如果相同,则说明有长度为k+1的前缀和长度为k+1的后缀相同
例如:ababa
如果上一次遍历到第3个字符和第1个字符相同,则这一次只要比较第4个字符和第2个字符相同则说明——第1,2个字符和第3,4个字符相同
---------------------------------------------------------------乱入的文字结束-------------------------------------------------------------------------------
模式串预处理过程
abababac
(从第二个字符开始匹配,红色表示前缀,绿色表示后缀,黄色表示相交的部分,蓝色表示两个字母比较)
第1次:a != b , k = 0 , (串:ab , k=0则下次还从第一个字符开始匹配)
第2次:a = a , k = 1 , (串:aba , k=1则下次从第二个字符开始匹配)
第3次:b = b , k = 2 , (串:abab , k=2则下次从第三个字符开始匹配)
第3次:a = a , k = 3 , (串:ababa , k=3则下次从第四个字符开始匹配)
第4次:b = b , k = 4 , (串:ababab, k=4则下次动第五个字符开始匹配)
...
由此可见,其整理过程只遍历了一次模式串
实际匹配过程
大家可以参考这个:http://ds.fzu.edu.cn/fine/resources/FlashContent.asp?id=40
其中偏移距离计算公式为:s = i - π[i-1](i为第一次不同的位置,则i-1为最后一次相同的位置)