题意:找出所有匹配串中的最长公共子串,长度须大于3
数据小,从长度为大到小枚举吧
#include<stdio.h>
#include<string.h>
#define val 65
int next[val],tot;
char p[val],s[11][val];
char ans[val];
bool kmp(char *,char *);
int main()
{
int cas,i,j,k,n;
bool found;
for(scanf("%d",&cas);cas;cas--)
{
memset(ans,0,sizeof(ans));
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%s",&s[i]);
for(i=0;i<60;i++) ans[i]='Z';
found=false;
for(i=60;i>=3&&!found;i--)//枚举所有长度
for(j=0;j<60;j++)//枚举起点
{
if(j+i>60) break;
// printf("J:%d END:%d\n",j,j+i);
tot=0;
for(k=j;k<j+i;k++)//输入模式串p
p[tot++]=s[0][k];
p[tot]=0;
// puts(p);
for(k=1;k<n;k++)//匹配模式串
if(kmp(s[k],p)==false) break;
if(k>=n)
{
found=true;
if(strcmp(p,ans)<0) strcpy(ans,p);//字典序靠前
}
}
// printf("END!\n");
if(!found) printf("no significant commonalities\n");
else puts(ans);
}
return 0;
}
bool kmp(char *s,char *p)
{
void set_next(char*);
int i,j,lens,lenp;
i=j=0;
set_next(p);
lens=strlen(s);
lenp=strlen(p);
while(i<lens&&j<lenp)
{
if(j==-1||s[i]==p[j])
{
i++;
j++;
}
else j=next[j];
}
if(j==lenp) return true;
else return false;
}
void set_next(char *p)
{
int j,k,lenp;
lenp=strlen(p);
j=0,k=-1;
next[j]=k;
while(j<lenp)
{
if(k==-1||p[j]==p[k])
{
j++;
k++;
if(p[j]==p[k]) next[j]=next[k];
else next[j]=k;
next[j]=k;
}
else k=next[k];
}
}