标签:kmp
2 abcdefghijklmnopqrstuvwxyz abcdab qwertyuiopasdfghjklzxcvbnm qwertabcde
abcdabcd qwertabcde
这道题花了很长时间啊。。。题意也很长时间才看懂,题意是这样的:给你一个26字母表,这些代表的是原来顺序的字母表变成密文后所对应的字母,如样例中的qwertyuiopasdfghjklzxcvbnm,那么原来的‘a‘就变成了‘q‘,‘b‘变成了‘w‘.然后再给你一个字符串,里面包含了密文和原文,其中顺序一定是先密文,后原文,但原文不一定写全,可能有缺少,问你把密文和明文补充完整输出。
思路:因为密文一定比明文长或者相等,所以(len-1)/2个字符一定是密文,先把它们转化为明文,然后和后面的明文进行匹配,看最后从哪个字符开始后面的所有字符可以和密文匹配,一直到最后,那么这个字符就是明文的开始。然后就可以先输出密文,再输出明文了。
#include<stdio.h> #include<string.h> char s1[100006],s2[100006],s[100006],s3[100],s4[100006]; int len1,len2,next[100006]; void nextt() { int i,j; i=0;j=-1; memset(next,-1,sizeof(next)); while(i<len2){ if(j==-1 || s2[i]==s2[j]){ i++;j++;next[i]=j; } else j=next[j]; } } int kmp() { int i,j; i=0;j=0; while(i<len1 && j<len2){ if(j==-1 || s1[i]==s2[j]){ i++;j++; } else j=next[j]; } return j; } int main() { int n,m,i,j,T,len,t,k; scanf("%d",&T); while(T--){ memset(s1,0,sizeof(s1));memset(s2,0,sizeof(s2)); scanf("%s%s",s3,s4); len=strlen(s4); for(i=0;i<len;i++){ for(k=0;k<26;k++){ if(s3[k]==s4[i]){ s[i]='a'+k;break; } } if(i<=(len-1)/2)s2[i]=s[i]; } for(i=(len-1)/2+1;i<len;i++){ s1[i-(len-1)/2-1]=s4[i]; } //printf("%s %s\n",s1,s2); nextt(); len1=strlen(s1);len2=strlen(s2); t=len-kmp(); //printf("%d\n",kmp()); for(i=0;i<t;i++)printf("%c",s4[i]); for(i=0;i<t;i++){ for(k=0;k<26;k++){ if(s3[k]==s4[i]){ printf("%c",'a'+k); } } } printf("\n"); } return 0; }
标签:kmp
原文地址:http://blog.csdn.net/kirito_acmer/article/details/46507107