我的题解(3)-求最小循环节(KMP,POJ2406)

本文介绍了一种利用KMP算法求解字符串最小循环节的方法,通过next数组的性质,阐述了如何确定最小循环节的长度,并通过三个命题证明了这种方法的正确性。在理解next数组的基础上,通过简单的代码实现,可以解决POJ2406题目中的问题。
摘要由CSDN通过智能技术生成

    KMP(烤馍片)算法想必大家都会吧,这次让我们来做一道题——求最小循环节。

 

    先上题,题目大意是这样的(我对原题进行了一些改动):给你一个字符串s(|s|≤1,000,000),求其最小循环节最小循环节指有一s的子串a,s=aaa...a,也就是共n个a可顺序拼成原串s(原题是说s=a^n)。

    样例:

    1.abcd 最小循环节为其本身

    2.aaaa 最小循环节为a

    3.ababab 最小循环节为ab

   很多大佬会说:这不是弱智题吗?那你就错了,请看我慢慢道来。

   首先看到这道题,第一反应应该就是哈希(划掉)KMP,我们对它进行一个变形。

   从哪里入手呢?想想next数组?

   首先,我们看看next数组的定义

   next[i]=max{k<i|s[1..k]=s[i-k+1..i]}

   通俗地讲,next[i]表示s的前i个字符构成的子串t中t的前缀与后缀相等的最长长度

   这个大家都懂的吧,如果还不知道KMP,那么先学学吧。

  看了这个,大家是否有什么感觉了呢?next...相等...前缀与后缀...循环节!只有前缀与后缀相等,这个前缀(或后缀)才有可能是循环节!

   不错,其实我们根本就不用考虑KMP的匹配,用next数组就可以求出答案。

   讲到这里,一般的解题博客就开始贴代码了,emmm...要不我也贴个代码?吐舌头

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
char s[1000001];
int Next[1000001],lens,nextN;
void getNext(){
	int k=0;
	Next[1]=0;
	for(int i=2;i<=lens;i++){
		while(k&&s[k+1]!=s[i]) k=Next[k];
		if(s[k+1]==s[i]) k++;
		Ne
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值