这个题数据很小 暴力瞎搞都能过
我试了试kmp
我看大部分题解复杂度都不低
我的复杂度大概 n*m*(n+n)
就是枚举第一个串的后缀来匹配后面的串 找到最长能匹配多少 选取最小的匹配长度为ans 就是这个后缀和其余串的公共部分了
然后在这一堆ans里面最大的就是结果
之所以写这篇题解是因为
memcpy每次只会从头开始复制传递的参数个 如果你的数组里之前是AAAAA 那么复制ABC进去后数组会变成ABCAA而不是ABC!
我在这个地方错了4、5发
#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
using namespace std;
int knext[10010];
char s[100][1000];
void kmp_pre(char x[],int m, int knext[]){
int i,j;
j = knext[0] = -1;
i = 0;
while(i<m){
while(-1!=j && x[i]!=x[j])j = knext[j];
knext[++i] = ++j;
}
}
int kmp_count(char x[], int m, char y[], int n){
int i,j;
int ans = 0;
kmp_pre(x,m,knext);
i = j = 0;
while(i < n){
while(-1 != j &&y[i]!= x[j])j = knext[j];
++i;++j;
ans = max(ans,j);
}
return ans;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
int n;
scanf("%d",&n);
char t1[1000];
memset(t1,0,sizeof(t1));//一定要加!
for(int i = 1;i<=n;++i){
scanf("%s",s[i]);
}
int res = 0;
for(int i = 0;i<strlen(s[1]);++i){
int ans = 0x3f3f3f;
for(int j = 2;j<=n;++j){
int len1 = strlen(s[1]+i);
int num = kmp_count(s[1]+i,len1,s[j],strlen(s[j]));
ans = min(ans,num);
}
//cout<<"I:"<<i<<"ans:"<<ans<<endl;
if(ans>res){
res = ans;
memcpy(t1,s[1]+i,res);
}
else if(ans&&ans==res){
char temp[100];
memcpy(temp,s[1]+i,res);
if(strcmp(t1,temp)>0){
memcpy(t1,temp,res);
}
}
}
if(res<3){
printf("no significant commonalities\n");
}
else{
printf("%s\n",t1);
}
}
}