2

luogu 3375 KMP模板题

#include<bits/stdc++.h>
using namespace std;
const int N = 1000100,M = 1100;
int next[N];
void getNext(char s[])    //找next数组
{
    int len=strlen(s+1);    //确保调用s中的元素的时候是从s[1]开始而不是s[0],因为next数组从1开头 
    for (int i=2,j=0;i<=len;i++) {
    //从第二个元素开始匹配,因为第一个元素一定不存在前缀,j=0是因为next[0]=0
    //next数组记录的是到第i位为止前面这段字符串的前缀和后缀的共有部分的长度 
        while (j && s[i]!=s[j+1]) j=next[j];    //就是移动过程 
        if (s[i]==s[j+1]) j++;    //如果匹配就继续
        next[i]=j;    //表明第i位的next[i]的值是j 
    }
} 
void kmp(char s[],char t[])    //在s中找t
{
    int lens=strlen(s+1),lent=strlen(t+1);    //同上 
    for (int i=1,j=0;i<=lens;i++) {        //注意是从s的第一位开始匹配
         while (j && s[i]!=t[j+1]) j=next[j];    //经典移动过程 
         if (s[i]==t[j+1]) j++;        //如果匹配就继续 
         if (j==lent) printf("%d\n",i-lent+1);        //输出(现在的位置-需要寻找的字符串的长度+1)就是这个字符串第一次出现的位置 
    } 
} 
int main()
{
    char a[N],b[M];
    cin>>a+1>>b+1;
    getNext(b);
    kmp(a,b);
    return 0;
    //洛谷评测改c++别用c++11,用流输入输出要关流输入 ios::sync_with_stdio(false) 
}

来自题解

posted @ 2017-10-20 14:11  DDYYZZ  阅读(222)  评论(0编辑  收藏  举报