KMP理解与学习-详细详细详细

本文详细介绍了KMP算法的工作原理及实现过程,并通过实例演示了next数组的构造方法及其在字符串匹配中的应用。

文章图片来自:
如何更好地理解和掌握 KMP 算法?
下面总结了一下:

首先上代码:

char s[10001];//待匹配
char p[101];//匹配
int nxt[1001];
int ls,lp;//分别代表s,p的长度,在主函数里求一次,最好别在kmp里求,容易超时
void get_next()//求next数组的代码,我一般喜欢把数组定义成全局变量,然后就不用在括号写东西了
{
    int i=0,j=-1;
    nxt[0]=-1;
    while(i<lp)//最好别写strlen(p),因为每次用都会算的话容易超时
    {
        if(j==-1||p[i]==p[j])
            nxt[++i]=++j;
        else
            j=nxt[j];//看清楚,这一步i没有变
    }
}
int kmp()//kmp算法,其实跟求nxt差不多
{
    int i=0,j=0;
    get_next();
    while(i<ls&&j<lp)
    {
        if(j==-1||s[i]==p[j])
            i++,j++;
        else j=nxt[j];//这一步i没有变,回溯
    }
    if(j==lp)//说明找到了
        return i-j+1;//返回下标
    else
        return -1;
}

以abababca求next数组为例:(lp=8)

从下标为1的元素开始,如图,现在模拟执行get_next()函数,i=1;j=-1;nxt[0]=-1;
i<lp,进入循环,由于此时,j=-1;执行if语句:nxt[1]=0;i=1;j=0;第一次循环执行完毕;此时i=1;j=0,如图a所示;
在这里插入图片描述

i= =2<lp,进入循环,此时,j= =0!=-1且p[i]!=p[j];执行else,j=nxt[1]=0;循环结束;
i= =2<lp,进入循环,此时,j= =0!=-1但是p[i]==p[j] (如图b),执行if语句,nxt[3]=1;j=1;i=3;循环结束;

在这里插入图片描述

i= =3<lp,进入循环,此时,j= =1!=-1但是p[i]==p[j],如图c,执行if语句,nxt[4]=2;i=4,j=2;循环结束;
在这里插入图片描述
i= =4<lp,进入循环,此时,j= =2!=-1但是p[i]==p[j],执行if语句,nxt[5]=3;i=5,j=3;循环结束;
i= =5<lp,进入循环,此时,j= =3!=-1但是p[i]==p[j],执行if语句(如图d),nxt[6]=4;i=6,j=4;循环结束;
在这里插入图片描述
重点来了,带你了解回溯:
i= =6<lp,进入循环,此时,j= =4!=-1且p[i]!=p[j],执行else语句,j=nxt[4]=2,循环结束;
i= =6<lp,进入循环,此时,j= =2!=-1且p[i]!=p[j],执行else语句,j=nxt[2]=0,循环结束;
i= =6<lp,进入循环,此时,j= =0!=-1且p[i]!=p[j],执行else语句,j=nxt[0]=-1,循环结束;
i= =6<lp,进入循环,此时,j= =-1;执行if语句(如图e):nxt[7]=0;i=7,j=0;循环结束;

在这里插入图片描述

i= =7<lp,进入循环,此时,j==0;但是p[i]==p[j],执行if语句:nxt[8]=1;i=8,j=1;循环结束,get_nxet()函数执行完毕

最后就形成了这个表:
在这里插入图片描述
添加链接描述

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JdiLfc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值