程序员宝典上的原题,求一个字符串中连续出线次数最多的子串,知道string 中substr的功能做题会方便很多。大案中使用了后缀数组。
substr[0] = abcbcbcabc
substr[1] = bcbcbcabc
substr[2] = cbcbcabc
substr[3] = bcbcabc
substr[4] = cbcabc
substr[5] = bcabc
substr[6] = cabc
substr[7] = abc
substr[8] = bc
substr[9] = c
注意到后缀数组的作用可以被代替,这样减少了存储空间。
有后缀数组
pair<int, string> CSubs(const string& str)
{
vector<string>substrs;
int maxcount = 1, count = 1;
string substr;
int i, len = str.length();
for(i = 0; i < len; i++)
{
substrs.push_back(str.substr(i, len - i));//构建后缀数组
}
for(int i = 0; i < len; i++)
{
for(int j = i+1; j < len; j++)
{
count = 1;
if(substrs[i].substr(0,j-i) == substrs[j].substr(0,j-i))
{
count++;
for(int k = j + j - i; k < len; k += j-i)
{
if(substrs[i].substr(0,j-i) == substrs[k].substr(0,j-i))
count++;
else
break;
}
if(count > maxcount)
{
maxcount = count;
substr = substrs[i].substr(0,j-i);
}
}
}
}
return make_pair(maxcount,substr);
}
无后缀数组
pair<int, string> CSubs_None(const string& str)
{
//vector<string>substrs;
int maxcount = 1, count = 1;
string substr;
int i, len = str.length();
/*
for(i = 0; i < len; i++)
{
substrs.push_back(str.substr(i, len - i));//构建后缀数组
}
*/
for(int i = 0; i < len; i++)
{
for(int j = i+1; j < len; j++)
{
count = 1;
if(str.substr(i,j-i) == str.substr(j,j-i))//str中起点为j,长度j-i,相当于上面的substrs[j].substr(0,j-i)(第j个字符串起点为0,长度为j-i的子串)
{
count++;
for(int k = j + j - i; k < len; k += j-i)
{
if(str.substr(i,j-i) == str.substr(k,j-i))
count++;
else
break;
}
if(count > maxcount)
{
maxcount = count;
substr = str.substr(i,j-i);
}
}
}
}
return make_pair(maxcount,substr);
}