【黑客大赛】前缀真前缀

(编程题)
对于两个字符串B和C,我们定义BC为将C接在B的后面形成的新串。一个字符串P是串A的前缀,当且仅当存在B使得A=PB,当然B可以为空串。若P!=A,则我们称P为A的真前缀。现在定义重复词。串Q是串A的重复词当且仅当Q是A的真前缀,且A是QQ的前缀。而A的最长重复词则是A的重复词中最长的一个,或者空串(当A没有任何重复串时)。如ababab的最长重复词是abab;abc的最长重复词是空串。
给定一个串s(由字母组成),及它的长度n(1≤n≤100000),请返回s的所有前缀的最长重复词的长度之和(空串长度为0)。
测试样例:
8,”babababa”
返回:24

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <numeric>
//#include <functional>
using namespace std;
bool mycompare(string str1,string str2)
{
return str1.size() > str2.size();
}
int main()
{
int chNum;/字符串中的字符个数
while(cin>>chNum)
{
string str1;
char ch;//每次输入的字符
for(int i = 0; i < chNum+2;i++)
{
cin>>ch;
str1 += ch;
}
//cout<<str1<<endl;//测试生成的string是对的
///得到str1的所有前缀和真前缀
//得到正规的string "babababa"-------babababa
str1.erase(0,1);
str1.erase(str1.size()-1,1);
vector<string>strVecAllPrefix;
string strAllPrefix;
//string strTruePrefix;
for(int i = 0; i < str1.size();i++)
{
strAllPrefix += str1[i];
strVecAllPrefix.push_back(strAllPrefix);
//strVecTruePrefix.push_back(strAllPrefix);
}
vector<string>strVecTruePrefix(strVecAllPrefix.begin(),strVecAllPrefix.end()-1);
//strVecTruePrefix.erase(strVecTruePrefix.end()-1);
/存储前缀的最长重词的个数
vector<int>iVec;
///找每一个前缀的多个重复词
for(int i = 0; i < strVecAllPrefix.size();i++)
{
string strTemp = strVecAllPrefix[i];/临时字符串,存放每一个前缀的
string str2;//临时字符串,存放每一个前缀的真前缀
vector<string>strVecRepeat;
for(int j = 0; j < strTemp.size()-1;j++)
{
str2 += strTemp[j];每一个前缀的真前缀
//strVecRepeat.push_back(str2);
string str2str2 = str2+str2;
string str3;//临时字符串,存放str2str2的前缀

for(int k = 0; k < str2str2.size();k++)
{
str3 += str2str2[k];
if(strTemp == str3)
{
strVecRepeat.push_back(str2);
//break;
}
}
}
if(!strVecRepeat.empty())
{
sort(strVecRepeat.begin(),strVecRepeat.end(),mycompare);
int len = strVecRepeat[0].size();
iVec.push_back(len);
}
else
{
iVec.push_back(0);
}
}
cout<<accumulate(iVec.begin(),iVec.end(),0)<<endl;
}
system("pause");
return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值