扩展KMP

扩展KMP


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

其实 nexti n e x t i 的求法也是类似的。
考虑每拓展一次 ed e d 至少 +1 + 1 ,所以时间复杂度是 O(n) O ( n ) 的。
实现中有个细节就是 ed e d 要和 i1 i − 1 取一个 max max
代码:

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;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值