Felicia's life问题描述: 有一天,Felicia收到公司发的一篇文章,文章很长,而且全是英文。不过这不要紧,要命是是,上司要她找出文章里重复出现过的内容,并且要找出最长的长度。要是那篇文章是很短的话,那也没所谓,问题就是这篇文章太长了,你能帮帮她吗? 输入:多组测试数据,一行为一组数据,每行为一个字符串,串长小于1000输出:对每组数据输出最长的重复出现的串的长度。 样例输入: abcabc abababab abcdefg qqqqqqqqqq abcdefghiabcefgfghiabd 样例输出: 3 4 0 5 6 解法: 第一个即是简单暴力搜索:
#include<iostream>
#include<string>
using namespace std;
char inp[1001];
int l[1001],ma=1,d[1001];
//string inp;
int main()
{
int le;
while(scanf("%s",inp)!=EOF)
{
le=0;
while(inp[le]!='/0') le++;
ma=le/2;
//if(le%2!=0) max++;
for(;ma>=1;ma--)
{
for(int i=0;i<=le-ma*2;i++)
{
for(int j=i+ma;j<=le-ma;j++)
{
for(int k=0;k<ma;k++)
{
if(j+k>=le||inp[i+k]!=inp[j+k])
goto next;
}
cout<<ma<<endl;
goto end;
next:;
}
}
}
cout<<"0"<<endl;
end:;
}
}
从可能最长的重复内容向下搜索。遇到满足的情况就直接给出结果。 但是显然会TLE。 第二个dp方法:
#include<stdio.h>
#define MAX_LONG 1000
long num[MAX_LONG];
int main()
{
long n1, n2, nl;
char c1[MAX_LONG];
char c;
long *p1=num;
while( scanf("%s", c1) != EOF )
{
long nMax = 0;
for(nl=0;c1[nl];nl++)
;
p1[0]=0;c=*c1; //init
for(n2=1;c1[n2];n2++) //初始化,和第一个字符做比较。
{
if(c1[n2]==c)
{
p1[n2]=1;
}
else
{
p1[n2]=0;
}
}
for(n1=1;c=c1[n1];n1++) //dp
{
p1[n1]=0;
for(n2=nl-1;n2>n1;n2--) //对于n1后面的字符搜索
{
if(c1[n2]==c) //如果和n1相同
{
p1[n2]=p1[n2-1]+1; //则这个字符串的长度+1
if(p1[n2]>n2-n1)p1[n2]=n2-n1; //这个字符串一定在n2和n1之间
else if(p1[n2]>nMax)nMax=p1[n2];
}
else //如果和当前比较的字符不同,则重新开始计算。
{
p1[n2]=0;
}
}
}
printf("%d/n", nMax);
}
return 0;
}