ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Password(KMP)

2021-05-24 20:36:06  阅读:164  来源: 互联网

标签:int ne next maxn && KMP Password 回文


传送门
刚开始练KMP题目,自己好菜啊...
这道题思路大致上对了,但是细节上出现了很大的偏差。
问题在于对于回文串的情况没有想全,仅仅想到了非重复回文串如abcdeabc以及单一回文串aaaaaa,于是考虑了两种情况,但是还有一种就是重复非单一回文串,用我的思路直接是求出next数组,分情况讨论,对于非单一的肯定就一种情况,但是如果出现abcabcabc那么 next[n] 就会是6,而目标是用3来求,不仅如此还打算用扩展kmp,Z算法来求,于是这样就错了。

看了题解才发现自己完全想多了,只需要在遍历中判断next[i]是否等于next[n]就可以了,这样就能保证是满足题意的,同时在求next数组中求出除了最后一位的next最大值,设其为maxn,有可能maxn是小于n的,那么这样就不满足条件如aaaaa,next[4] = 3 != next[5],所以要将长度缩小,也就是将首尾相同的串的长度缩小,直到小于等于这个中间最长串。

#include <bits/stdc++.h>
using namespace std;

const int N = 1e6 + 10;
char s[N];
int ne[N], ne1[N], extend[N];
int maxn = 0;
int main(){
	scanf("%s", s + 1);
	int n = strlen(s + 1);
	for(int i = 2, j = 0; i <= n; i ++){
		while(j && s[i] != s[j + 1])
			j = ne[j];
		if(s[i] == s[j + 1])
			j ++;
		ne[i] = j;
		if(i != n)
			maxn = max(maxn, ne[i]);
	}
	if(ne[n] == 0){
		cout << "Just a legend" << endl;
		return 0;
	}
	int x = ne[n];
	while(maxn < x)
		x = ne[x];
	if(x == 0){
		cout << "Just a legend" << endl;
		return 0;
	}
	for(int i = 2; i <= n - 1; i ++){
		if(ne[i] == x){
			for(int j = n - ne[i] + 1; j <= n; j ++){
				printf("%c", s[j]);
			}
			return 0;
		}
	}
	
	//以下为废弃代码
	/*string str, p;
	p += "@";
	for(int i = 2; i <= n - 1; i ++)
		p += s[i];
		
	cout << ne[n] << endl;
	if(ne[n] > 0 && s[1] != s[n]){
		for(int i = n - ne[n] + 1; i <= n; i ++)
			str += s[i];
		str = "@" + str;
		int len = ne[n];
		for(int i = 2, j = 0; i <= n - 2; i ++){
			while(j && p[i] != p[j + 1])
				j = ne1[j];
			if(p[i] == p[j + 1])
				j ++;
			ne1[i] = j;
		}
		for(int i = 2, j = 0; i <= n - 2; i ++){
			while(p[i] != str[j + 1] && j)
				j = ne1[j];
			if(p[i] == str[j + 1])
				j ++;
			if(j == len){
				for(int i = n - ne[n] + 1; i <= n; i ++)
					printf("%c", s[i]);
				return 0;
			}
		}
		printf("Just a legend\n");
	}else if(ne[n] > 0 && s[1] == s[n]){
		for(int i = n - ne[n] + 1; i <= n; i ++)
			str += s[i];
		int len = ne[n];
		getExtend(p, str);
		int maxn = -1;
		for(int i = 1; i <= n - 2; i ++)
			maxn = max(maxn, extend[i]);
		for(int i = 1; i <= n; i ++)
			cout << extend[i] << ' ';
		cout << endl;
		for(int i = n - maxn + 1; i <= n; i ++)
			printf("%c", s[i]);
	}
	*/
	
	return 0;
} 

标签:int,ne,next,maxn,&&,KMP,Password,回文
来源: https://www.cnblogs.com/pureayu/p/14806027.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有