【数据结构】 串 KMP算法实现
KMP算法应用于串的模式匹配中
普通模式匹配算法在进行匹配时需要频繁对主串指针进行回溯,KMP算法通过将模式向右滑动一段距离的方式避免了主串的回溯,同时降低了算法复杂度 ,由原来的O(n*m)变为O(n)。
KMP算法本身比较容易理解,就是对模式串本身的结构进行分析,在匹配过程中跳过一些不必要的步骤。
比如当模式串为ababc; 主串为ababdddd时; 匹配进行到第五个字符处时失败了,但是这时主串指针不必进行回退(又重新从第二个字符b处开始比较),只需要根据模式串的 nest 函数,将模式指针进行移动,再进行下一次判断。
next函数求解
KMP算法难以理解的点在于 next 函数的求解。
要弄明白一些基本的东西:
在比较的过程中,存在着两个指针,
- 主串指针,指向当前主串正在进行比较的字符
- 模式串指针,指向模当前正在匹配的模式串的字符位置
在使用KMP算法时,主串是不会进行回溯的,只有右移操作,主要是对模式串指针的滑动操作。
算了,写不下去了
弄懂之后才知道为什么书上写得那么晦涩难懂了。因为实在是很难说明白
1.递推
2.这个问题可以看成一个模式匹配问题,整个模式串既是主串,又是模式串。
3.在求解 next【n+1】的过程中,其实还是在进行模式匹配,可以通过已知的next来获得next【n+1】
4.后面的优化:对于 第 j 个字符 ,如果与next [ j ]所指示的字符相等,那么 next [ j ] = next [ next[j] ].
想要理解整个算法,建议自己照着书上的思路走一遍,写一遍代码,模拟整个函数的执行过程,差不多懂了之后再回过头看看定义 (网上很多详解都没有把整个思路讲清,还得自己悟)
代码部分:
下面是KMP算法的实现,代码中串采用堆分配存储表示,书中串的存储方式为定长顺序串,代码略有区别
1.采用KMP算法的模式匹配函数
int Index_KMP(HString S, HString T, int pos,int next[]) {
//利用模式串T的next函数求T在主串中第pos个字符之后的位置的KMP算法。
int i = pos;
int j = 0;
while (i<S.length&&j<T.length)
{
if (j == -1 || S.ch[i] == T.ch[j]) {
++i; ++j; }
else
{
j = next[j];
}