很不详细的KMP

这篇博客介绍了KMP算法的基本概念和核心思想,包括next数组的构建和匹配过程。博主简化了next数组的构建方法,并解释了KMP算法如何利用失配信息进行快速匹配,达到O(n)的时间复杂度。此外,还提到了算法的匹配过程和模板代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

KMP

我都初三了还不会KMP……

全称The Knuth-Morris-Pratt Algorithm,三个大佬同时发明
只适用于单模匹配,可以求子串在母串中出现的位置次数等东西

普通匹配是失配了重新从母串下一位、子串第一位开始匹配,最坏时间复杂度O(nm)O(nm)
KMPKMP思想核心是建立nextnext数组,利用失配信息快速匹配,最坏时间复杂度O(n)O(n)


next

网上其他教程写next写的跟sh*t一样
我写简单一点,对于子串的每一位建nextnext

  • ii位的next表示以ii为结尾的最长的、且从第一位字符开始存在的字符串的末尾位置

这个可以子串自己和自己匹配实现
如果当前建next到第ii位,看一下next[i]+1位和i+1i+1相不相同
相同的话next[i+1]=next[i]+1next[i+1]=next[i]+1,否则i=next[i]i=next[i]重新回溯做
(大概像把i+1i+1nextnext再指向nextnextnextnext,有点像ACAC自动机)

所以next是往前跳的为什么叫做next


匹配

搞完nextnext,匹配很简单
i,ji,j分别是母串、子串匹配到了哪一位
如果i,ji,j位置不匹配就j=next[j]j=next[j],否则i++,j++i++,j++
j==lenj==len子串,就匹配成功一次
多次匹配就继续做KMPKMP直到ii指针==len


code

  • 丢个模板
#include<stdio.h>
#include<string.h>
#define MAXN 100005

using namespace std;

char s1[MAXN],s2[MAXN];
int len1,len2,i,j,k;
int next[MAXN];

void init()
{
    k=-1,j=0;
    next[0]=-1;
    while (j<len2)
    {
        if (k==-1 || s2[k]==s2[j])
        {
            j++;
            k++;
            next[j]=k;
        }
        else k=next[k];
    }
}

void kmp()
{
    j=0;
    while (i<len1 && j<len2)
    {
        if (j==-1 || s1[i]==s2[j])i++,j++;
        else j=next[j];
    }
    if (j==len2)printf("%d\n",i-j+1);
}

int main()
{
    scanf("%d%d",&len1,&len2);
    scanf("%s%s",s1,s2);
    init();
    kmp();
    while (1)
    {
        if (i==len1) break;
        i=i-j+2;
        kmp();
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值