题目链接:https://vjudge.net/problem/HDU-2328
还是在多个字符串中寻找最长公共子串
从第一个字符串里找子串和其他字符串匹配,有多个最长的输出字典序最小的
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=200+10; //文本串长度
const int M=200+10; //模式串长度
char a[N]; //文本串
char b[M]; //模式串
int next0[M];
char s[4010][N];
void find_next()
{
int len=strlen(b);
int k=-1;
next0[0]=-1;
int j=0;
while(j<len-1)
{
if(k==-1||b[j]==b[k])
{
j++;
k++;
next0[j]=k;
}
else
{
k=next0[k];
}
}
}
int kmp()
{
int i=0;
int j=0;
int alen=strlen(a);
int blen=strlen(b);
while(i<alen&&j<blen)
{
if(j==-1||a[i]==b[j])
{
i++;
j++;
}
else j=next0[j];
}
if(j==blen) return i-j+1; //返回查找到的位置
return -1; //查找失败
}
int main()
{
int n;
while(~scanf("%d",&n)&&n)
{
for(int i=0;i<n;i++) scanf("%s",s[i]);
int len=strlen(s[0]);
int cnt=0;
char ans[N];
for(int i=0;i<len;i++)
for(int j=1;j<=len-i;j++) //从第一个字符串里找模式串
{
for(int k=0;k<j;k++)
b[k]=s[0][i+k];
b[j]='\0';
find_next();
bool flag=true;
for(int k=1;k<n;k++) //对每个文本串进行匹配
{
strcpy(a,s[k]);
if(kmp()==-1)
{
flag=false;
break;
}
}
if(flag) //全部匹配
{
if(j>cnt) //比较长度
{
cnt=j;
strcpy(ans,b);
}
if(j==cnt&&strcmp(ans,b)>0) strcpy(ans,b); //长度相同比较字典序
}
}
if(cnt==0) printf("IDENTITY LOST\n"); //没有找到
else printf("%s\n",ans);
}
return 0;
}