在洛谷上我自己写的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; }