求解最长不重复子序列(后缀数组)

//微软编程一小时 第二题  求解最长重复子序列

#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;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值