pku3450 Corporate Identity &&pku3080 Blue Jeans(枚举+KMP)
题意:求多个串的最长公共子串
pku3450用KMP算法
#include<iostream> #include<algorithm> #include<string.h> using namespace std; int nxt[210]; char str[4010][210],s[210]; int n,m; bool KMP(char *T,char *P) { memset(nxt,0,sizeof(nxt)); nxt[0]=-1; int k=-1; for(int q=1;q<m;q++) { while(k>-1&& P[k+1]!=P[q]) k=nxt[k]; if(P[k+1]==P[q]) k++; nxt[q]=k; } int j=-1,i=0; while(T[i]) { while(j>-1 && P[j+1]!=T[i]) j=nxt[j]; if(P[j+1]==T[i]) j++; if(j+1==m) return true; i++; } return false; } int main() { int t; while(scanf("%d",&t)==1 && t) { int l,min1=10000; for(int i=0;i<t;i++) { scanf("%s",str[i]); if(strlen(str[i])<min1) { min1=strlen(str[i]); l=i; } } char os[210],ans=0; for(int i=0;i<strlen(str[l]);i++) { for(int j=i;j<strlen(str[l]);j++)//变量i和j 用来枚举字串的首和尾 { int b=0; for(int k=i;k<=j;k++)//枚举最短字串的长度,正串和反串 os[b++]=str[l][k]; os[b]='\0'; m=b; int flag=1; for(int k=0;k<t;k++) { if(!KMP(str[k],os)) { flag=0;break; } } if(flag&&ans<strlen(os)) { strcpy(s,os); ans=strlen(os); } else if(flag && ans==strlen(os)) { if(strcmp(s,os)==1) strcpy(s,os); } } } if(ans>0) printf("%s\n",s); else puts("IDENTITY LOST"); } return 0; }
pku3450用strstr()函数
#include<iostream> #include<algorithm> #include<string.h> using namespace std; char str[4010][210],s[210]; int n,m; int main() { int t; while(scanf("%d",&t)==1 && t) { int l,min1=10000; for(int i=0;i<t;i++) { scanf("%s",str[i]); if(strlen(str[i])<min1) { min1=strlen(str[i]); l=i; } } char os[210],ans=0; for(int i=0;i<strlen(str[l]);i++) { for(int j=i;j<strlen(str[l]);j++)//变量i和j 用来枚举字串的首和尾 { int b=0; for(int k=i;k<=j;k++)//枚举最短字串的长度,正串和反串 os[b++]=str[l][k]; os[b]='\0'; int flag=1; for(int k=0;k<t;k++) { if(!strstr(str[k],os))//正串和反串都没有在字符串在出现 { flag=0;break; } } if(flag&&ans<strlen(os)) { strcpy(s,os); ans=strlen(os); } else if(flag && ans==strlen(os)) { if(strcmp(s,os)==1) strcpy(s,os); } } } if(ans>0) printf("%s\n",s); else puts("IDENTITY LOST"); } return 0; }
pku3080
#include<iostream> #include<algorithm> #include<string.h> using namespace std; int nxt[100]; char str[15][110],s[110]; int n,m; bool KMP(char *T,char *P) { memset(nxt,0,sizeof(nxt)); nxt[0]=-1; int k=-1; for(int q=1;q<m;q++) { while(k>-1&& P[k+1]!=P[q]) k=nxt[k]; if(P[k+1]==P[q]) k++; nxt[q]=k; } int j=-1,i=0; while(T[i]) { while(j>-1 && P[j+1]!=T[i]) j=nxt[j]; if(P[j+1]==T[i]) j++; if(j+1==m) return true; i++; } return false; } int main() { int cas,t; scanf("%d",&cas); while(cas--) { scanf("%d",&n); int l,min1=10000; for(int i=0;i<n;i++) { scanf("%s",str[i]); if(strlen(str[i])<min1) { min1=strlen(str[i]); l=i; } } char os[210],ans=0; for(int i=0;i<strlen(str[l]);i++) { for(int j=i;j<strlen(str[l]);j++)//变量i和j 用来枚举字串的首和尾 { int b=0; for(int k=i;k<=j;k++)//枚举最短字串的长度,正串和反串 os[b++]=str[l][k]; os[b]='\0'; m=b; int flag=1; for(int k=0;k<n;k++) { if(!KMP(str[k],os)) { flag=0;break; } } if(flag&&ans<strlen(os)) { strcpy(s,os); ans=strlen(os); } else if(flag && ans==strlen(os)) { if(strcmp(s,os)==1) strcpy(s,os); } } } if(ans>=3) printf("%s\n",s); else puts("no significant commonalities"); } return 0; }