这是一道非常简单的搜索题目,我是一个搜索的初学者,我是根据杭电的pdf资料上的搜索入门的思想来做这题的,上面说的方法很简单。STL+枚举就可以做出来,当然了,这题不用STL也是可以的,但是既然我们已经有了直接可用的模板,为什么还要自己写呢。所以不会的同学,建议要学习STL再去做搜索的题目吧,因为里面太多用到STL了,不会的话,你会很痛苦的。好吧,说说正题吧。
题目的大意就是找出一个最长字符串或者他的反串,是的这个字符串在所有给出的字符串中都可见(必须连续)。
那么杭电的思想就是先将字符串按长度从短到长排序,枚举最短的字符串的子串,判断是否都是别的字符串的子串,求出最大长度即可,我是按照这个思想来的。
这里需要用到STL中的find()函数,这个函数返回的是查找到的字符或字符串的位置,找不到就会返回4294967295,我也不明白这个怎么来的,我们暂且不论。
#include<iostream>
using namespace std;
#include<algorithm>
#include<string>
int main()
{
string a[105];
string c;
string b;
int T,N,i,j,k,Max,t;
int leap;
cin>>T;
while(T--)
{
memset(a,0,sizeof(a));
leap=0;
k=0;
Max=0;
cin>>N;
for(i=0;i<N;i++)
cin>>a[i];
for(i=0;i<N-1;i++)
for(j=i+1;j<N;j++)
if(a[i].size()>a[j].size())
{
b=a[i];
a[i]=a[j];
a[j]=b;
}
c=a[0];
for(i=0;i<a[0].size();i++)
{
for(j=1;i+j<=a[0].size();j++)
{
string d(a[0],i,j); //这里是string的用法,他可以直接取字符串d=从a[0]的第i个开始,共j个1.
string e=d;
reverse(d.begin(),d.end()); //这个函数是STL中的求反串的函数
for(t=1;t<N;t++)
{
if(a[t].find(d)!=4294967295||a[t].find(e)!=4294967295)//这里就是STL里面的find()函数
leap=1;
else
{
leap=0;
break;
}
}
if(leap==1)
{
k=j;
if(k>Max)
Max=k; //这个就是求得最长的额子串
}
else break;
}
}
cout<<Max<<endl;
}
return 0;
}
下面再说一种别人的比较好处理的两个地方:
(1)上面的j表示所取的串的长度,我们可以将j的初值赋值为最短串的长度,然后依次减小,当减小到某一值的时候满足条件,这时的j就是所求的最大长度。
(2)我所用的是将所有的串排序找出最小的,其实没有必要,因为我们要的是最小的,不是顺序,那么我们就可以直接用一个for循环找出最小的。
(3)string d(a[0],i,j);这种方法不是很好,因为你不能事先定义d,那么这里介绍一个具有相同功能,可以事先定义的函数substr(i,k);使用方法是:
定义string a;a=b.substr(i,k);a是你要找的子串,b是你现在正在里面找子串的母串,i是起始位置,k是多少个字符。