洛谷P5410 拓展KMP 模板题

15 篇文章 0 订阅
1 篇文章 0 订阅

洛谷P5410 拓展KMP 模板题

KMP算法大家应该都知道,拓展KMP顾名思义,就是在KMP算法上面的扩展和加难。

拓展KMP的经典题型就是:给你两个串,让你求一个串的后缀子串与另一个串的最长公共前缀LCP的长度(用ex数组存下)

具体理解可以参照刘雅琼前辈的扩展KMP的PPT

https://wenku.baidu.com/view/64ac5384b9d528ea81c779ed.html

上代码

#pragma GCC optimize("O2")
#include <bits/stdc++.h>
#define ll long long
using namespace std;  
const int maxn=2e6+7;
char str[maxn],tr[maxn];
int l,li,nxt[maxn],ex[maxn];//nxt实际上就是自己对自己的ex数组,ex就代表每一个后缀串对模板串的最长公共前缀(LCP)的长度
void ekmpgetnxt(){
    int a=0,p=0;//p代表最长匹配的长度,a代表开始匹配的位置
    nxt[0]=l;
    for(int i=1;i<l;i++){
        if(i>=p || i+nxt[i-a]>=p){
            if(i>=p) p=i;
            while(p<l && str[p]==str[p-i])
                p++;
            nxt[i]=p-i,a=i;
        }
        else nxt[i]=nxt[i-a];
    }
    for(int i=0;i<l;i++)
        printf("%d ",nxt[i]);
    cout<<endl;
}
void ekmp(){
    int i=0,j,p0=0;
    li=strlen(tr);//母串的长度(不做getnxt的长度)
    while(i<li && i<l && str[i]==tr[i]) i++;//注意都是i
    ex[0]=i;
    for(int i=1;i<li;i++){
        if(nxt[i-p0]+i<ex[p0]+p0)   ex[i]=nxt[i-p0];
        else{
            j=ex[p0]+p0-i;
            if(j<0) j=0;
            while(i+j<li && j<l && tr[i+j]==str[j])   j++;
            ex[i]=j;
            p0=i;
        }
    }
    for(int i=0;i<li;i++)
        printf("%d ",ex[i]);//输出母串的ex数组(即每一个后缀串对母串的最长公共前缀)
    cout<<endl;
}
int main(){
    scanf("%s",tr);
    scanf("%s",str);
    l=strlen(str);
    ekmpgetnxt();
    ekmp();
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值