算法学习系列之二章---KMP算法图解

来源:互联网 发布:java 垃圾收集器 编辑:程序博客网 时间:2024/05/16 19:46

一、简介

        KMP算法,首先与BF算法做比较…….(此处略去简介200字,至于哪200字,网上随便找一篇讲KMP算法的基本上都会先讲朴素算法);

二、题外话

        记得大二的时候,DS课程设计就是实现KMP算法,当时也没弄太清楚(或者弄清楚了也忘记了),就知道在网上搜到了代码,然后就好用!然而这几天抱着深入学习的态度,反而有点晕,可能年纪大了吧!在网上找到很多资料把我看的直接拔电源了都!我想说的是,根据自己这两天在网上的搜索可知,很多关于KMP算法的介绍的文章,篇幅都比较长,没有心情看下去,而且感觉不能突出重点,我只想问,有那么复杂吗?也许是优化版很多吧。那么,接下来,我们就用图标的方式,来分析一下,这个算法到底有多复杂。

三、主题

        主题没有代码,只有图表。下面,我们就以


为例,我们来学习这个算法的思想。

1. 关于Next数组

什么是Next数组,Next数组时干嘛的呢?不知道?那就自己搜搜去。

这个算法的关键,就是Next数组的构造与使用,使用当然就很简单,主要的是来看看构造。


我们将KMP原始算法 与 KMP改进算法对比着来看。

原始算法

1. Next[0] = -1:因为由失配发生时,模式串跳转的位置为:右移动j - Next[j]长度.

                       若在首位置失配,只能右移一位,类似朴素算法,所以要右移一位,又要将这种情况套入:j - Next[j] 因此,只能为-1

2. Next[j] 的值为:

                         若存在一个k,使得:模式串的前 Next[0],Next[1]... Next[k-1]) 个字符与Next[j-k],Next[j-k+1]Next[j-1]相等,则    Next[j] = k;

                         若不存在一个k,使得:模式串的前 Next[0],Next[1]... Next[k-1]) 个字符  与   Next[j-k],Next[j-k+1]Next[j-1]相等,则    Next[j] = 0;

改进算法:

1. 1.Next[0] = -1;同上

2. .Next[j] 的值为:

                          若存在一个k,使得:模式串的前 Next[0],Next[1]... Next[k-1]) 个字符  与   Next[j-k],Next[j-k+1]Next[j-1]相等,并且 Next[k] != Next[j]    则   Next[j] = k否则若Next[k] == Next[j]   则   Next[j] = -1;

                         若不存在一个k,使得:模式串的前 Next[0],Next[1]... Next[k-1]) 个字符  与   Next[j-k],Next[j-k+1]Next[j-1]相等,并且 Next[0] == Next[j]    则   Next[j] = -1否则若Next[0] != Next[j]   则   Next[j] = 0;

 

根据以上原则,我们来计算一下我们的模式串的Next函数



//根据以上的图我们知道Next数组的计算了,至于代码,我就只贴一下改进算法的好了void GetNextval(const SWORD *pswPattern, SDWORD *psdNext, SDWORD sdLength ) { // 求模式串pswPattern的next函数值并存入数组 next。SDWORD j = 0, k = -1; psdNext[0] = -1; while ( j < sdLength ) { if ( k == -1 || pswPattern[j] == pswPattern[k] ) { ++j; ++k; if ( pswPattern[j] != pswPattern[k] ) {psdNext[j] = k; }else {psdNext[j] = psdNext[k]; }}else {k = psdNext[k]; }}}

OKNext数组我们求出来了,我们再列个表格来展示一下两种算法的匹配过程吧

原始算法



改进算法:



四、结语

          Sunday算法是另外一种匹配算法,据说比KMP要高效,还没学习,等以后学习了再加上吧。《算法导论》上关于KMP的内容基本上都是一些理论证明,如果数学比较好的童鞋可以看看,如果只是为了应用,那么,网上随便找到的完整代码都是可以用的了。

可能我的表述有些简单,或者哪里表述的不对,还请诸位指正,因为这两天有点懵圈了,难免有疏漏或者理解错误之处,敬请原谅。


0 0
原创粉丝点击