求字符串中循环子串的长度 ← KMP算法

【题目来源】
改编自:https://www.luogu.com.cn/problem/P4391

【问题描述】
给你一个字符串 s1​,它是由某个字符串 s2​ 不断自我连接形成的。但是字符串 s2​ 是不确定的,现在只想知道它的最短长度是多少。

【输入格式】
仅一行,表示输入字符串 s1​ 的一个子串。

【输出格式】
仅一行,表示 s2​ 的最短长度。

【说明/提示】
样例cabcabca的解释:对于样例,我们可以利用abc不断自我连接得到abcabcabc,读入的cabcabca是它的子串。

【规模与约定】
对于全部的测试点,保证字符串的长度 ≤10^6 。

【算法分析】
首先要注意,本题输入的字符串比较特殊,是由某个字符串不断自我连接构成的某个字符串的子串。在这个基础上,绘制样例 cabcabca 的前缀表及next数组如下文示意图所示。
由 
https://blog.csdn.net/hnjzsyjyj/article/details/127171330 知,前缀表与next数组虽然是有关系的,但是它们不是一回事。且next数组可通过“将前缀表每一位都向右移动1位(最右位舍去)并在最左位补一个-1”得到。
观察示意图可知,循环子串的长度为:
T.length()-ne[T.length()]

 
【算法代码】

#include<iostream>
using namespace std;
 
const int maxn=100;
int ne[maxn];
 
void getNext(string T) {
	int len=T.length();
	int i=0, j=-1;
	ne[0]=-1;
	while(i<len) {
		if(j==-1 || T[i]==T[j]) {
			ne[++i]=++j;
		} else j=ne[j];
	}
}
 
int main() {
	string T;
	getline(cin,T);
	getNext(T);
	cout<<(T.length()-ne[T.length()]);
 
	return 0;
}
 
 
/*
in1: cabcabca
out1: 3

in2: ac@# ac@# ac@# 
out2: 5
*/



【参考文献】
https://blog.csdn.net/hnjzsyjyj/article/details/127112363
https://blog.csdn.net/hnjzsyjyj/article/details/127086502
https://blog.csdn.net/hnjzsyjyj/article/details/127105603
https://www.luogu.com.cn/problem/solution/P4391
https://www.luogu.com.cn/problem/P4391
https://blog.csdn.net/hnjzsyjyj/article/details/120330090

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值