写下本篇仅因为自己学到了点东西记录一下~
如果是szu的uu看到了不要直接复制粘贴交oj球球了
//查重你懂的,别跟我自爆一起拿0分啊啊啊啊啊啊啊啊啊啊啊
还有就是这题老师应该是希望我用KMP写的,但是有函数为什么不用捏~
题目描述:
求串的最长重复子串长度(子串不重叠)。例如:abcaefabcabc的最长重复子串是串abca,长度为4。
输入
测试次数t
t个测试串
输出
对每个测试串,输出最长重复子串长度,若没有重复子串,输出-1.
输入样例1
3
abcaefabcabc
szu0123szu
szuabcefg
输出样例1
4
3
-1
以下为本人代码
#include<iostream>
#include<string>
using namespace std;
int main()
{
int t;
cin >> t;
while (t--)
{
string str;
cin >> str;
int len = str.length();
/*if (len == 1)
{
cout << "1" << endl;
break;
}*/
//如果对单一字符有要求结果为1的话
int maxlength = 0;
int flag = 0;
for (int i = 0; i < len; i++)
{
for (int j = i+1; j < len; j++)
{
string mode = str.substr(i,j-i);//mode为子串
string tmpstr;//tmpstr为去掉mode串后的str串
if (i >= 1)//将i以前的字符赋值到tmpstr1上,方便进行拼接比较(当前mode可能会与i之前的子串有重复
{
string tmpstr1 = str.substr(0, i);
tmpstr += tmpstr1;
}
string tmpstr2 = str.substr(j, len-j);
tmpstr += tmpstr2;
if (tmpstr.find(mode)= -1&& maxlength < mode.length())
{
flag = 1;
maxlength = mode.length();
}
}
}
if (flag == 1)
cout << maxlength << endl;
else
cout << "-1" << endl;
}
}
为方便展示代码运行原理,以下贴出运行过程中mode串、tmpstr串以及maxlength的数值
从中不难发现还有以下可以改进的地方
·当mode串比tmpstr串长时,已经没必要比较了,因为tmpstr中不可能再找到子串与mode相同。由此我们可以优化为:当mode串比tmpstr串长时退出比较,i++
·若str串为”aaabbcabbc“,mode串为“aabbc",当i=1时,tmpstr串会变成”aabbc”,但显然我们拼接tmpstr1和tmpstr2的本意是同时将前后比较,即将“aa”和mode比,“bbc”与mode比。由此我们可以酱紫优化:拼接tmpstr1和tmpstr2时在中间加个任何字符防止进行了ab连接比较。
至于为什么我代码里不是优化过的。
鹅,过都过了是吧!!!知道可以优化就好啦!!!
学到的东西:
find函数:可在str中找到s出现的位置,返回值为首次出现时的头下标。用法为——index=str.find(s)。如果要从指定位置开始查找,则可这么用——str.find(s,pos),就可以在str中从pos开始找s出现的位置。这个函数的返回值为string::npos,故可以用if(str.find(s)==string::npos)或者if(str.find(s)!=-1)来判断是否在str中找到了s
substr函数:返回index开始的n个字符组成的字符串。用法为:s=str.substr(index,n)。若写成 str.substr(index) ,则返回的是index起往后的字符串