ITPub博客

首页 > 应用开发 > IT综合 > 史上最透彻的KMP算法讲解

史上最透彻的KMP算法讲解

IT综合 作者:DicksonJYL560101 时间:2018-01-06 15:48:48 0 删除 编辑

史上最透彻的KMP算法讲解

 

http://mp.weixin.qq.com/s/XzcAAspIDoQaRlfycsDrRw

 

 

1

字符串匹配是经典的KMP算法。下面以字符串"BBC ABCDAB ABCDABCDABDE"为例,查找是否包含串"ABCDABD"?

http://mmbiz.qpic.cn/mmbiz_png/iaTa8ut6HiawB6ticutybgB9sgs8MODqGwx4VNrHuqNMkJbSQ9FmsVKF0fuVckOhDEq5RYLxddEsEXhq9ZQzj4N6A/640?wx_fmt=png&wxfrom=5&wx_lazy=1

图一

2

     首先如上图,字符串"BBC ABCDAB ABCDABCDABDE"的第一个字符与搜词"ABCDABD"的第一个字符,B与A不相等,所以后移动。

http://mmbiz.qpic.cn/mmbiz_png/iaTa8ut6HiawB6ticutybgB9sgs8MODqGwxKibBcGY6hhzicb4n5tKnZ15cm6raWrbsnmpVvic4f08t5q2HbiafajyxyA/640?wx_fmt=png&wxfrom=5&wx_lazy=1

图二

 

3      上图中,D与空格不相等,但是它有前缀AB与后缀AB相当,KMP的思想就是利用最长的公共前缀与最长公共后缀相等,来加快每次不相等时移动的距离,来提高搜索效率。

http://mmbiz.qpic.cn/mmbiz_png/iaTa8ut6HiawB6ticutybgB9sgs8MODqGwxcfrP1S9lOnobuL40g1XbXpAibXCIJv395EGMVD7gvkibUILK3vvFmJjA/640?wx_fmt=png&wxfrom=5&wx_lazy=1

4

     要做到这一点,就是要生成一个next匹配数组,next匹配数据来决定匹配的最大长度。如图二。查next数组可知,最后一个匹配字符B对应的"部分匹配值"为2,因此后移动的位数:移动位数 = 已匹配的字符数 - 对应的部分匹配值。因为 6 - 2 等于4,所以将搜索词向后移动4位。

http://mmbiz.qpic.cn/mmbiz_png/iaTa8ut6HiawB6ticutybgB9sgs8MODqGwxNOFJkO1IOJSMLerJcOV7NOVHD5bwazEBDeOXygE2wXribevtxC6yvIA/640?wx_fmt=png&wxfrom=5&wx_lazy=1

下面是next数组和匹配算法参照代码。

精彩内容

 

#include <iostream>

#include <cstring>

using namespace std;

 

const int N = 1000002;

int next[N];

char S[N], T[N];

int slen, tlen;

 

void getNext()

{

    int j, k;

    j = 0; k = -1; next[0] = -1;

    while(j < tlen)

        if(k == -1 || T[j] == T[k])

            next[++j] = ++k;

        else

            k = next[k];

 

}

/*

返回模式串T在主串S中首次出现的位置

返回的位置是从0开始的。

*/

int KMP_Index()

{

    int i = 0, j = 0;

    getNext();

 

    while(i < slen && j < tlen)

    {

        if(j == -1 || S[i] == T[j])

        {

            i++; j++;

        }

        else

            j = next[j];

    }

    if(j == tlen)

        return i - tlen;

    else

        return -1;

}

 

 

 

 

 

 

 

 

 

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29829936/viewspace-2149803/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
行万里路,读万卷书,阅无数人。 吃货一枚,爱吃湘菜,粤菜与杭帮菜,尝遍天下美食。 摄影爱好者,游遍名川大山,江河胡海,赏遍人间春色。 爱看电影,尤其是国产大片,好莱坞大片。英文名:Dickson Jin, 网名:风一样的BOY。精通SAP供应链咨询。2017年开始研习人工智能。

注册时间:2014-08-27

  • 博文量
    2598
  • 访问量
    4671368