ICode9

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

017(Power Strings二刷)(KMP)

2022-05-15 12:04:01  阅读:173  来源: 互联网

标签:qnext a0 int len next 二刷 KMP 区块 Strings


题目:http://ybt.ssoier.cn:8088/problem_show.php?pid=1466

题目思路:不知道大家在KMP算法里有没有看见这么个句子

while(j<len)

这是找next数组的时候的游标范围

这说明 j 总有走到 len-1 的时候

但是这也说明了一个问题,next[len] 是一定有值的

要么 a[k]==a[j],要么就是 k 走到了-1

而我们今天要做的题就与这个被赋值的 next[len] 有关系

(注意:以下的两种情况都默认 j=len-1)

首先,如果是 k 走到了-1 这种情况

那next[len]会得零,这他妈跟没赋值有什么区别吗

接下来顺着另一种思路剖析

当 a[k]==a[j] 的时候可能会是

ACA

k    j

或者

AABAABAAB

             k     j

。。。。。。数不过来

但是它也有规律可循

这边以X,Y,Z这三个大写字母为字符区块来推导

发现,k 永远是会离 j 所在的区块最近的一个相同区块的最后一个

比如

X X X Y X

此时的 k 会在第三个区块的最后一个

这是可以与 j 呼应上的

或者

Y Y Y Y

此时的 k 就会在第三个区块的最后一个字符上

接下来就是重点了

next[j] 是等于 k 的

并且由于区块相同

我是可以得到从 k+1~len-1 的这块,也就是最后一块区块的长度的

如果这种时候 len 还可以整除这个区块的长度的话

那不就是等于说:“嘿,前面的东西我都对应好了,你放心大胆的用!”

循环节以及循环节的个数,全部白给

 

#include<bits/stdc++.h>
using namespace std;
string a;
int a0,qnext[1000001];
void hnext(string o,int o0){//next数组 
	int j=0,k=-1;
	qnext[j]=k;
	while(j<o0){
		if(k==-1||o[j]==o[k]){
			qnext[++j]=++k;
		}
		else{
			k=qnext[k];
		}
	}
}
int main(){
	while(1){
		cin>>a;
		if(a=="."){
			return 0;
		}
		a0=a.size();
		hnext(a,a0);
		if(a0%(a0-qnext[a0])==0){//能整除
			printf("%d\n",a0/(a0-qnext[a0]));
			//白给 
		}
		else{//不能 
			printf("1\n");
			//中间被某个B区块拦路了
			//直接出1就得了 
		}
	}
	return 0;
}

 

题目总结:这题的关键在于找到可能的循环节的长度

对某些模板程序探索一下会有意想不到的惊喜

标签:qnext,a0,int,len,next,二刷,KMP,区块,Strings
来源: https://www.cnblogs.com/a-001/p/16272759.html

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

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

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

ICode9版权所有