在洛谷上我自己写的KMP的demo是AC的,但是上次在集训中写的KMP居然WA了,后来参考别人的代码,加上网上的标程,发现这样写不仅代码短,而且跑起来没有漏洞。但有几个地方弄不懂,只好先强记了。。。

传送门:http://blog.csdn.net/no1_terminator/article/details/52925547

#include<iostream>
#include<iomanip>
#include<ctime>
#include<climits>
#include<algorithm>
#include<queue>
#include<vector>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<map>
using namespace std;
typedef unsigned long long LL;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
inline int read(){
    int x=0;char ch=getchar();
    while(ch<'0'||ch>'9'){
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x;
}
char s[1000001],t[1001];
int next[1001];
void kmp(char*t,int*next){//求解next数组
    next[0]=next[1]=0;
    int len=strlen(t);
    rep(i,1,len-1){
        int j=next[i];
        while(j&&t[i]!=t[j])j=next[j];
        next[i+1]=t[i]==t[j]?j+1:0;
    }
}
int KMP(char*s,char*t,int*next){
    int j=0;
    int lens=strlen(s),lent=strlen(t);
    rep(i,0,lens-1){
        while(j&&s[i]!=t[j])j=next[j];
        if(s[i]==t[j])j++;
        if(j==lent)printf("%d\n",i-lent+1+1);//输出模式串每次在字符串中出现的位置
    }
}
int main(){
    scanf("%s",s);
    scanf("%s",t);
    kmp(t,next);
    KMP(s,t,next);
    rep(i,1,strlen(t))printf("%d ",next[i]);
    return 0;
}