不好意思我的头快炸了。。。
辣鸡KMP算法。。我只知道我晚上的代码在简化版和正式版之间疯狂转化,甚至于一道题先写简化版再写正式版,再换成简化版,又换成正式版。。。
简而言之,KMP就是用于比对字符串的一个算法,且可以将字串的位置求出的一个莫名算法。。
顺带一提,此题必须用KMP的正式版,因为要输出next数组,而该题的next数组是在KMP正式版代码下所求出的next数组
1 #include<set> 2 #include<map> 3 #include<list> 4 #include<queue> 5 #include<stack> 6 #include<string> 7 #include<cmath> 8 #include<ctime> 9 #include<vector> 10 #include<bitset> 11 #include<memory> 12 #include<utility> 13 #include<cstdio> 14 #include<sstream> 15 #include<iostream> 16 #include<cstdlib> 17 #include<cstring> 18 #include<algorithm> 19 using namespace std; 20 21 int lena,lenb; 22 int next[1000005]; 23 char z[1000005],y[1000005];//两个串 24 25 void pre(){//对于子串next数组的预处理,也就是一个字符串对自身的KMP 26 int j=0; 27 next[1]=0; 28 for(int i=1;i<lenb;i++){ 29 while(j>0&&y[i+1]!=y[j+1]){ 30 j=next[j]; 31 } 32 if(y[i+1]==y[j+1]){ 33 j++; 34 } 35 next[i+1]=j; 36 } 37 } 38 39 void KMPMatch(){//KMP算法正式版程序 40 int j=0; 41 for(int i=0;i<lena;i++){ 42 //printf("%d %d ",i,j); 43 while(y[j+1]!=z[i+1]&&j>0){ 44 j=next[j]; 45 } 46 //cout<<z[j+1]<<' '<<y[i+1]<<endl; 47 if(y[j+1]==z[i+1]){ 48 j++; 49 } 50 if(j==lenb){//若匹配到了子串,则输出位置 51 printf("%d ",i+1-j+1); 52 i=i+1-j;//将下标移到子串第一个下标+1的位置 53 j=0; 54 } 55 //printf("%d %d ",i,j); 56 } 57 } 58 59 int main(){ 60 cin>>z+1; 61 cin>>y+1; 62 lena=strlen(z+1); 63 lenb=strlen(y+1); 64 pre();//预处理出next数组,此处借鉴了某dalao题解的函数名 65 KMPMatch();//KMP 66 for(int i=1;i<=lenb;i++){ 67 printf("%d ",next[i]); 68 } 69 return 0; 70 }
那就这样了,我要睡了,再不睡我就要死了。。。