KMP-字符串快速查找

http://www.ruanyifeng.com/blog/2013/05/Knuth–Morris–Pratt_algorithm.html

字符串匹配的KMP算法 

转载一下,UP主已经写的很详细了,超赞!!

/////////////////////////////////////割//////////////////////////////////////////////////////

对KMP算法,网上可真是铺天盖地的介绍,说什么的都有,未免会让人看的摸不到头脑,为了把代码敲出来,看了几个up主的视频,哔哩哔哩上面有,这里我就简介一下,尽量简单清楚!

首先就是next[]数组,我要首先告诉你的是

shuzuabcdabd
next0000120

这个next是绝对对的,但为什么我们见到的next都是这样的呢?

next-1000012

这个是使用在程序里面的,把真正的next向后移动一位即可。

 

好,我们接着说KMP怎么用程序实现,这里楼主试着使用一种很通俗的比喻来代替,当然,这个可以选择不看,因为我发现如果有人问KMP原理是什么,我发现很难表述,倒不如打个比方,心里清楚,能够呼之欲出就OK,懂得程序怎么写。

/*

初始化next[]做为存放,cur作为变量初始值cur=0,cur[0]=0;

shuzu[]存放用户输入字符串,j作为变量初始值j=1;
eg1:abcdabca

我们观察发现,如果shuzu[j] !=shuzu[cur],即a!=d

很大程度直接next[j]就等于0了,但是发现,咦,shuzu[j]==shuzu[0]啊,那他填1,

我们总结:如果计算机走啊走啊,一直都相等,突然发现第shuzu[j]!=shuzu[cur],直接写cur=0;
然后判断shuzu[0]==shuzu[j],不就行了?找这个不匹配元素是否与第一个元素相等,好像很完美啊!
但是很不幸还有一种特殊情况

eg2:ABCDABCDEABCDABCDAF
老大顾不上你个小事情,那好吧,一级一级向上反映嘛
可以找老大的“代理人”谈,
代理人怎么找?
ABCDABCDE   与    ABCDABCDA在第九处不匹配,此时cur=8,j=13;

使cur=next[cur-1];
解释一下:
next[cur-1]=next[7]=4;
这个next[7]存放的4是什么意思呢,
说明前八个元素可以凑成一对,最长长度4,
既然成对,那也就是说shuzu[4]就是我shuzu[0]的代理人
我可以比较shuzu[4]==shuzu[j]
这样cur=4;而不是cur=0;

eg3:abcdabd

abc与abd
第三个元素不匹配,行,这次吸取经验,谁让可能会出错呢,那就一级一级上访
cur=next[cur-1]=next[1];
很明显next[1]=0;所以cur=0;
看来最终还是交给老大处理了嘛。。。。

*/

我们通俗的码一下代码:求真实的next[]

void  get_next(char *shuzu,int *next)//传进要求next值的数组
{
    int cur=0,j=1;//初始化两个变量作为游标
    next[cur]=0;//直接把第一个元素赋0
    while(j<len)//len=strlen(shuzu)
    {
        if(shuzu[cur]==shuzu[j])
        {
            cur++;       
            next[j++]=cur;//如果匹配接着往下面走,j先使用再加一
        }else
        {
            if(cur>0)
                cur=next[cur-1];
            else
                next[j++]=0;//此时cur已经等于零
        }    
    }

}

这时把得到的next[]转换为程序需要的,只需要全部向后移动一位,把next[0]=-1即可

void move(char *next)
{
    for(int i=n-1;i>0;i--)//n为next长度
    {
        next[i]=next[i-1];
    }
    next[0]=-1;
}

准备工作做好,可以写KMP了

void  search_KMP(char *shuzu,char *T)//输入搜索和被搜索串,返回找到时候的位置
{
    int cur,j;
    while(j<strlen(shuzu))
    {
        if(cur==-1||shuzu[j]==T[cur])//如果T的首个元素也不匹配,统一向下移动一个元素
        {
            if(cur=strlen(T)-1)//找到匹配
            {
                cout<<"POS:"<<j-cur;
                cur=next[cur];//继续寻找
            }
            j++;
            cur++;            
        }else
        {
            cur=next[cur];
        }
    }

}

《KMP-字符串快速查找》

先写到这里吧,KMP写法比较多,还有一种常见的,直接next[0]=-1;不需要移动,再更。。。。18/9/5

 

 

 

    原文作者:KMP算法
    原文地址: https://blog.csdn.net/shuiyihang0981/article/details/82355302
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞