这题是个搜索题。主要思想就是:首先,找到输入字符串中最短的串;然后,枚举其子串和子串的反串。这里求子串要从长度最大到最小,
因为要求的是最大子串。最后,判断枚举的子串是否是公共子串。若是,输出其长度,并结束;反之,继续求解。
在做题过程中遇到的问题就是,把bool flag1=false,flag2=false写到了for循环的外部,结果出现了莫名奇妙得错误!
AC代码如下:
#include<iostream>
using namespace std;
struct node
{
char ch[101];
int len;
}str[100];
int length,n; //length为最小串的长度
char tmp[101]; //放最小的串
void init() //输入数据,并找的最小的串
{
cin>>n;
length=10000;
for(int i=0;i<n;i++)
{
cin>>str[i].ch;
str[i].len=strlen(str[i].ch);
if(str[i].len<length)
{
length=str[i].len;
strcpy(tmp,str[i].ch);
}
}
}
void deal_subs()
{
int i,j,k,ii,jj;
char rev[101],norm[101]; //norm为子串,rev放子串的反串
char *st,*en; //st子串开始的地址,en子串结束的地址
j=0;
i=length;
while(i>=1) //i记录子串的长度
{
st=tmp+j;
if(i+j>length) //子串的长度和子串开始的位置和必须小于最小串的长度,否则子串越界
{
j=0;
i--;
continue;
}
else
en=st+(i-1);
char *p1=st;
k=0;
while(p1!=(en+1)) //获得子串
{
norm[k++]=*p1++;
}
p1=en;
k=0;
while(p1!=st) //获得反串
{
rev[k++]=*p1--;
}
rev[k]=*p1;
bool flag=false; //判断子串或其反串是否是公共子串
for(k=0;k<n;k++) //判断子串或其反串,是否是公共子串
{
bool flag1=false,flag2=false; //记录子串或其反串是否是某一输入数据子串
for(ii=0;ii<=str[k].len-i;ii++)
{
if(norm[0]==str[k].ch[ii])
{
for(jj=0;jj<i;jj++)
{
if(norm[jj]!=str[k].ch[ii+jj])
break;
else if(jj==i-1)
flag1=true;
}
}
if(flag1) break;
}
if(!flag1)
{
for(ii=0;ii<=str[k].len-i;ii++)
{
if(rev[0]==str[k].ch[ii])
{
for(jj=0;jj<i;jj++)
{
if(rev[jj]!=str[k].ch[ii+jj])
break;
else if(jj==i-1)
flag2=true;
}
}
if(flag2) break;
}
}
if(!(flag1 || flag2)) //若一子串或其反串不是至少一个输入数据的子串,则该子串不可能符合条件了
break;
if(k==n-1) //找到公共子串
flag=true;
}
if(flag)
{
cout<<i<<endl; //找到公共子串,函数结束
return;
}
j++;
}
cout<<0<<endl; //没有公共子串
}
int main()
{
int t_case;
cin>>t_case;
while(t_case--)
{
init();
deal_subs();
}
return 0;
}