扩展KMP

本文详细介绍了扩展KMP算法的工作原理及其应用。该算法能在线性时间内找出文本串的每个后缀与模板串的最长公共前缀。文章通过具体步骤解释了如何利用已知条件推导未知的最长公共前缀,并提供了实现代码。

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

扩展KMP


为了叙述方便,设S(i)S(i)为串SSi开始的后缀
扩展KMP可以在线性时间内求出对于一个文本串SS的每一个后缀S(i)与模板串TT的最长公共前缀(LCP),我们设其为exi
假设我们已经知道了T(i)T(i)TT的LCP,设为nexti,考虑怎么求exiexi
假设当前ex1exi1ex1∼exi−1,都已求出,设其中最大的exkexkeded,对应的kkst,那么分两种情况讨论:
1. nextist+1<edst+1nexti−st+1<ed−st+1;设w=nextist+1w=nexti−st+1,首先因为Sst..ed=T1..edst+1Sst..ed=T1..ed−st+1,那么S(i)=T(ist+1)S(i)=T(i−st+1)的LCP为ww,又因为T1..w=Tist+1..ist+w+1,得到exi=wexi=w
2. nextist+1edst+1nexti−st+1≥ed−st+1;同理,exiexi至少为edi+1ed−i+1,但还可能更多,暴力拓展eded即可。

其实nextinexti的求法也是类似的。
考虑每拓展一次eded至少+1+1,所以时间复杂度是O(n)O(n)的。
实现中有个细节就是eded要和i1i−1取一个maxmax
代码:

void ex_kmp(char s[],char t[],int nxt[],int ex[])
{
    int st=1,ed=0;
    nxt[1]=n;
    for(int i=2;i<=n;i++)
    {
        if(nxt[i-st+1]<ed-i+1) {nxt[i]=nxt[i-st+1];continue;}
        ed=max(i-1,ed);
        for(int j=ed-i+1;ed<n&&t[ed+1]==t[j+1];ed++,j++);
        st=i;nxt[i]=ed-i+1;
    }
    st=1;ed=0;
    for(int i=1;i<=n;i++)
    {
        if(nxt[i-st+1]<ed-i+1) {ex[i]=nxt[i-st+1];continue;}
        ed=max(i-1,ed);
        for(int j=ed-i+1;ed<n&&s[ed+1]==t[j+1];ed++,j++);
        st=i;ex[i]=ed-i+1;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值