枚举一个串的所有子串,和其余的串匹配,裸kmp的题。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 222;
const int maxd = 4010;
int f[maxn];
char str[maxn];
char t_str[maxn];
char c_str[maxd][maxn];
void init_kmp(char *s){
int L = strlen(s);
f[0] = 0; f[1] = 0;
for(int i = 1; i < L; i++){
int j = f[i];
while(j && s[i] != s[j]) j = f[j];
f[i + 1] = s[i] == s[j] ? j + 1 : 0;
}
}
int solve_kmp(char *s,int m){
int L = strlen(s);
int j = 0;
for(int i = 0; i < L; i++){
while(j && s[i] != t_str[j]) j = f[j];
if(s[i] == t_str[j]) j++;
if(j == m) return 1;
}
return 0;
}
int main(){
int n;
while(scanf("%d",&n) && n){
scanf("%s",str); //输入的第一个串,让它的子串作为模板进行匹配
for(int i = 0; i < n - 1; i++) scanf("%s",c_str[i]);
int L = strlen(str);
int len_max = 0; //最终长度
char ret_str[maxn]; //最终字符串
for(int i = L; i >= 1; i--){ //枚举子串的时候按照长度从小到大进行枚举
for(int j = 0; j + i <= L; j ++){
strncpy(t_str,str + j,i); //枚举一个子串
t_str[i + j] = '\0';
//printf("%d,%d:%s\n",i,strlen(t_str),t_str);
init_kmp(t_str); //构造状态转移函数
int ok = 1;
for(int k = 0; k < n - 1; k ++) //与每个字符串进行匹配
if(!solve_kmp(c_str[k],i)){ //如果没办法匹配
ok = 0;
break;
}
//if(ok) puts(t_str);
if(ok && i > len_max){
len_max = i;
strcpy(ret_str,t_str);
//puts(t_str);
}
if(ok && i == len_max && strcmp(ret_str,t_str) > 0){
//puts(t_str);
strcpy(ret_str,t_str);
}
}
if(i < len_max + 1) break;
}
if(!len_max) printf("IDENTITY LOST\n");
else printf("%s\n",ret_str);
}
return 0;
}