欢迎来到蒟蒻mqd的博客

P3375 【模板】KMP字符串匹配

题目链接

https://www.luogu.org/problemnew/show/P3375

题目描述

如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置。

为了减少骗分的情况,接下来还要输出子串的前缀数组next。

(如果你不知道这是什么意思也不要问,去百度搜`kmp算法`学习一下就知道了。)

输入输出格式

输入格式:

第一行为一个字符串,即为s1

第二行为一个字符串,即为s2

输出格式:

若干行,每行包含一个整数,表示s2在s1中出现的位置

接下来1行,包括length(s2)个整数,表示前缀数组next[i]的值。

输入输出样例

输入样例#1:

ABABABC
ABA

输出样例#1:

1
3
0 0 1

说明

时空限制:1000ms,128M

数据规模:

设s1长度为N,s2长度为M

N<=1000000,M<=1000000

题解

模板就不过多解释了。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 1000050
int n,m,nex[N];
char s[N]={"*"},ss[N]={"*"};
int main()
{
#ifndef ONLINE_JUDGE
    freopen("aa.in","r",stdin);
#endif
    scanf("%s %s",s+1,ss+1);
    n=strlen(s)-1;
    m=strlen(ss)-1;
    int k=0;
    for(int i=2;i<=m;i++)
        {
            while(k&&ss[k+1]!=ss[i])k=nex[k];
            if (ss[k+1]==ss[i])k++;
            nex[i]=k;
        }
    k=0;
    for(int i=1;i<=n;i++)
        {
            while(k&&ss[k+1]!=s[i])k=nex[k];
            if (ss[k+1]==s[i])k++;
            if (k==m)printf("%d\n",i-m+1),k=nex[k];
        }
    for(int i=1;i<=m;i++)printf("%d ",nex[i]);
}

posted @ 2019-05-12 01:27  mmqqdd  阅读(270)  评论(0编辑  收藏  举报