我的KMP实现

来源:互联网 发布:php关闭warning警告 编辑:程序博客网 时间:2024/06/05 05:25

前言

之前在搞ACM的时候了解过KMP,可是最近发现细节记不清楚了,索性重新看一遍这些基础的算法,我们先来看一下定义:“KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为克努特——莫里斯——普拉特操作(简称KMP算法)”。这里对KMP的定义是字符串匹配算法,当然这个算法不仅仅是用来处理字符串的,你可以应用于查找子序列的各种问题中。

KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是实现一个next()函数,函数本身包含了模式串的局部匹配信息,将时间复杂度从暴力匹配的O(mn)优化成了O(m+n)。现在我处于的状态是一个知其然也知其所以然的状态,也就是说知道KMP算法为什么要这样做,但是我确实没办法给第二个人讲得清清楚楚,简单来说还是功力不够,等我再练练一定给大家简单的讲一下。

内容

既然看了一天的算法总得有点收获,所以今天我决定根据自己的理解来实现以下KMP算法,代码如下,有什么不正确的地方欢迎大家指出来

  • KMP使用实例

  • 运行结果

find fam in aaaasdfhasidfahakfambfjawefjghfka postion : 17

总结

  • 这个算法最主要的就是实现next函数,也就是找到模板串中每个字符的前串的前缀和后缀公共部分的最大长度。
  • 在查找过程中要注意算法含义的转化,其中所说的模板串向后移动在代码中的实现看起来并不像移动,但含义是相同的。
  • 注意计算next函数和查找过程中不断分割子串的操作,我个人感觉这句代码while (nMatchCount > 0 && pPattern[nMatchCount] != pPattern[nIndex]) nMatchCount = pNext[nMatchCount];是KMP算法中最精妙的部分了,学习算法时要注意这句的理解。

另注

我决定在此处先画一条分割线,关于代码实现的细节和主要思想,我还没有想好怎么表达,待我组织清楚后,一定要静下心来写一写。。。



1 0