KMP学习笔记

前言:

重温一遍KMP,为接下来的AC自动机做准备!

KMP算法:

KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)。

看上去依旧很高大上,但是其实又是一种简单的方法

首先回顾一下暴力匹配

虽然看上去暴力也很好,但其实这有一个很大的弊病

回溯之后必然导致无法配对

这就吧把时间弄的很慢

这是我们便引入了KMP

如果j = -1,或者当前字符匹配成功(即S1[i] == S2[j]),都令i++,j++,继续匹配下一个字符;

如果j != -1,且当前字符匹配失败(即S1[i] != S2[j]),则令 i 不变,j = next[j]。此举意味着无法匹配时,S2相对于S1向右移动了j - next [j] 位。

而next数组又是什么呢?

next表示除当前字符最长相同的前缀后缀

怎么求呢?

void get_next()
{
    int len1=strlen(s2);
    next[0]=-1;
    int k=-1;
    int j=0;
    while(len1-1>j)
    {
        if((k==-1)||(s2[j]==s2[k]))
        {
            j++,k++;
            if(s2[j]!=s2[k])
            {
                next[j]=k;
            }
            else
            {
                next[j]=next[k];
            }
        }
        else
        {
            k=next[k];
        }
    }
}
CodeHelper

当next求出来了,KMP的思路也明了了:

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

加油!

转载于:https://www.cnblogs.com/zhouyifei/p/11135145.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值