KMP模版

题目描述

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

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

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

输入输出格式

输入格式:

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

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

输出格式:

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

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

思路

KMP很重要的。
一开始我next数组半天没搞懂。。。

其实就是自己与自己匹配。
每一次找一个相同的字母,不停地累上去,就可以求出next数组。

然后匹配,跟着数组跳即可。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1e6+7;
int next[maxn];
char s2[maxn],s1[maxn];
void spawn_next(char* st)
{
    int l=strlen(st),k=0;
    next[0]=-1;
    for(int i=0; i<l; i++)
    {
        k=next[i];
        while(k!=-1&&st[i]!=st[k]) k=next[k];
        next[i+1]=++k;
    }
}
int match(char* st,char* s)
{
    int l1=strlen(st),l2=strlen(s);
    int k=0;
    for(int i=0; i<l1; i++)
    {
        while(k!=-1&&st[i]!=s[k]) k=next[k];
        if(st[i]==s[k]) k++;
        if(k==l2) return i-l2+1;
    }
}
int kmp(char* st,char* s)
{
    spawn_next(st); return match(st,s);
}
int main()
{
    scanf("%s%s",s1,s2);
    int ass=kmp(s1,s2)+1;
    printf("%d",ass);
}
    原文作者:KMP算法
    原文地址: https://blog.csdn.net/eric1561759334/article/details/80070990
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞