DS串应用—最长重复子串

写下本篇仅因为自己学到了点东西记录一下~

如果是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”,但显然我们拼接tmpstr1tmpstr2的本意是同时将前后比较,即将“aa”和mode比,“bbc”与mode比。由此我们可以酱紫优化:拼接tmpstr1tmpstr2时在中间加个任何字符防止进行了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起往后的字符串         

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值