题目链接:http://poj.org/problem?id=1226
给一些字符串,求公共的最长子串的长度。
用到了KMP算法
我的解法很一般,先对字符串排个序,最短的在最前面。
然后通过枚举(从长到短)每一个最短串的子串,看其或其反串是否是其他所有串的子串。
代码:
#include <stdio.h>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
int n,m,p[101];
bool Comp(string s1,string s2)
{
return s1.length()<s2.length();
}
int kmp(string a,string b)
{
p[0]=-1;
int i,j=-1;
for(i=1;i<m;i++){
while(j>-1&&b[j+1]!=b[i]) j=p[j];
if(b[j+1]==b[i]) j+=1;
p[i]=j;
}
j=-1;
for(i=0;i<n;i++){
while(j>-1&&b[j+1]!=a[i]) j=p[j];
if(b[j+1]==a[i]) j+=1;
if(j==m-1){
return 1;
j=p[j];
}
}
return 0;
}
int main()
{
int t,h;
string s[100];
cin>>t;
while(t--)
{
cin>>h;
for(int i=0;i<h;i++)
cin>>s[i];
sort(s,s+h,Comp);
string a,b;
int len=s[0].length();
int flag=0;
for(int i=len;i>0;i--)
{
for(int j=0;j<=len-i;j++)
{
a=s[0].substr(j,i);
b=a;
reverse(b.begin(),b.end());
m=a.length();
int k;
for(k=1;k<h;k++)
{
n=s[k].length();
if(!(kmp(s[k],a)||kmp(s[k],b)))
break;
}
if(k==h){flag=1;break;}
}
if(flag)break;
}
if(flag)cout<<a.length()<<endl;
else cout<<0<<endl;
}
return 0;
}