**KMP算法**
KMP算法思想的精妙之处在于,KMP算法当遇到主串与模式串匹配失败的时候,主串不会向前移动,而是 主串不动,将模式串向前移动到next[j]的位置!
首先介绍一下KMP算法的主要思路,现在有两个字符串:main_string和pattern_string(主串和模式串),现在我们想要知道pattern_string是否是main_string的一部分(也就是是否是main_string的子串),算法步骤:
- 计算next数组,这个next数组就是上面我们提到的模式串移动的位置,下面我们将会详细讨论next数组的含义:
在模式串匹配的时候,假设主串第i个元素main_string[i]与模式串第j个元素pattern_string[j]匹配失败,那么至少可以确定的是pattern_string[0 -> j-1] 等于 main_string[i-j -> i-1],我们需要找到最大的k值,使pattern_string[0 -> k] 等于 main_string[i-k -> i-1],那么我们仅需继续向后匹配即可!让我们来看下面这个例子:
通过这个例子我们知道,当匹配失败时,仅需让模式串移动到next[j]位置,便可进行下一次匹配,但是目前我们并不会计算next数组的值,下面就让我们一起来看一看如何计算next数组的值:
由于next数组的原理是模式串自身有重复的子串,因此next数组的计算仅与模式串相关!
next数组的计算:
(1)首先next[0] = -1,-1代表着第一次就匹配错误,那么直接向后匹配(模式串没有任何前缀可供移动)。
(2)next[i] = Max{k| 1<k<j 且 pattern_string[0 -> k-1] 等于 pattern_string[i-k -> i-1]} (找出最长的相同前缀) - 此时模式串匹配有三种情况:(1):匹配成功,那么直接将主串和模式串向后移动一个位置,进 行下一次比较。
(2):匹配失败,那么模式串回退到next[j]的位置
(3):这种情况是第二种情况的特殊,next[j]=-1时,应该将主串和模式串向后移动一个位置,进行下一次比较(和第一种情况处理方式相同) - KMP算法的解释就到此为止了,下面附上KMP算法的代码:
main_string = "ababcabcacbab" # 主串
pa