KMP算法

最近复习了一下集训学的kmp算法。
kmp算法可以将字符串匹配的时间复杂度由 O(n2) O ( n 2 ) 降低到 O(nlogn) O ( n l o g n ) ,还有各种神奇的用途。
对于求一个串是否是另一个串的子串,可以先求出一个数组next[i],表示1到i中前缀等于后缀的长度。
然后kmp算法就是充分利用之前已知的数据,如果第i-1位的next数组是 next[i1] n e x t [ i − 1 ] ,那么对于第i个数,如果第i位与第next[i-1]+1位相同,那么就将next[i]赋值为next[i-1]+1.
如果没有成功配对,那么就找第next[next[i]]位的,如图
这里写图片描述
代码

//Writer:jr HSZ;%%%WJMZBMR
#include<bits/stdc++.h>
#define LL long long
#define reg register int
#define f(i,a,b) for(reg i=a;i<=b;i++)
using namespace std;
char tp[1000001],s[1000000*2+1];
int nxt[1000001*2];
int len,lent,len2;
void kmp() {
    int j=0;
    for(int i=2; i<=len; i++) {
        while(j>0&&s[i]!=s[j+1])
            j=nxt[j];
        if(s[i]==s[j+1])j++;
        nxt[i]=j;
        if(nxt[i]==len2&&i>len2+1)cout<<i-(len2)*2<<endl;
    }
}
int main() {
    cin>>tp+1;
    lent=strlen(tp+1);
    cin>>s+1;
    len2=strlen(s+1);
    s[len2+1]='*';
    for(int i=len2+2; i<=lent+len2+2; i++)s[i]=tp[i-len2-1];
    len=strlen(s+1);
    kmp();
    for(int i=1; i<=len2; i++)cout<<nxt[i]<<" ";
    cout<<endl;
    return 0;
}

睡觉ZZZ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值