//微软编程一小时 第二题 求解最长重复子序列
#include "iostream"
#include "string"using namespace std;
#define MAXLEN 10000
char a[MAXLEN],*suff[MAXLEN];
int comlen(char* p,char* q)
{
int maxlen =0;
while((*p)&&(*q)&&(*p==*q))
{
maxlen++;
p++;q++;
}
return maxlen;
}
int pstrcmp(const void* p,const void* q)
{
return strcmp(*(char**)p,*(char**)q);
}
void output(char array[],int len)
{
int index =0;
while(len--)
{
cout<<array[index++];
}
cout<<endl;
}
void LRS()
{
int size=strlen(a);
int maxlen =0,suff_index=0;
for (int i=0;i<size;i++)
{
suff[i] =&a[i];
}
qsort(suff,size,sizeof(char*),pstrcmp);//排序后缀
for (i=0;i<size-1;i++)
{
int len =comlen(suff[i],suff[i+1]);
if (len>maxlen)
{
maxlen =len;
suff_index =i;
}
}
output(suff[suff_index],maxlen);
}
void main()
{
cout<<"请输入原字符串:";
cin>>a;
LRS();
}
运行结果 如下:
2.方法二 Hash+DP(哈希+动态规划)
#include <iostream>
#include <string>
using namespace std;
char* GetMaxSubStr( char*str )
{
int hash[256]; //hash记录每个字符的出现位置
for (int i = 0; i < 256; i++)//初始化
{
hash[i] = -1;
}
int CurrentStart = 0, CurrentLength = 0, MaxStart = 0, MaxEnd = 0;
int strLen = strlen(str);
for(i = 0; i < strLen; i++)
{
if(CurrentStart > hash[str[i]]) //如果没有重复
{
hash[str[i]] = i;
}
else
{
CurrentLength = i - CurrentStart; //当前长度
if(CurrentLength > MaxEnd-MaxStart)//如果当前长度最长
{
MaxEnd = i;
MaxStart = CurrentStart;
}
CurrentStart = hash[str[i]] + 1; //更新当前最长的起点
hash[str[i]] = i; //更新字符出现的位置
}
}
if (MaxEnd == 0)//没有重复字符,返回源串
{
char* reStr = new char[strLen + 1];
strcpy(reStr, str);
return reStr;
}
CurrentLength = strLen - CurrentStart; //当前长度
if(CurrentLength > MaxEnd - MaxStart)//如果当前长度最长
{
MaxEnd = strLen;
MaxStart = CurrentStart;
}
int MaxLength = MaxEnd - MaxStart;
char* reStr = new char[MaxLength + 1];
memset(reStr, 0, MaxLength + 1);
strncpy(reStr, str + MaxStart, MaxLength);
return reStr;
}
int main()
{
string str = GetMaxSubStr("abcbef");
cout << str << endl;
return 0;
}