POJ 2406 Power Strings(KMP求最小循环节)

先简单介绍一下KMP算法利用 nxt 数组求最小循环节的原理:


假设图中的黑色是原来的字符串,现在要求最小循环节,对于nxt[len]来说指的是图中蓝色和黄色的长度,而且蓝色和黄色是相等的,

那么绿色和紫色也是相等的,,对比原串可知紫色跟粉色是相同的子串,那么绿色跟粉色相同,然后对比蓝色跟黄色可知红色跟粉色相同,对比原串,红色跟棕色相同,那么棕色跟粉色相同,不断重复此过程可知若此字符串有最小循环节,那么循环次数一定为len/(len-nxt[len])。

结论:如果len%(len-nxt[len])=0,那么循环次数为len/(len-nxt[len]),否则为1

#pragma warning(disable:4996)
#include <cstdio>
#include <cstring>
using namespace std;

char s[1000100];
int nxt[1000100];

void get_nxt(){
	int len = strlen(s);
	nxt[0] = -1;
	int i = 0, j = -1;

	while (i < len){
		if (j == -1 || s[i] == s[j]){
			i++, j++;
			nxt[i] = j;
		}
		else j = nxt[j];
	}
}

int main(){
	//freopen("in.txt", "r", stdin);
	while (scanf("%s", s)){
		int len = strlen(s);
		if (len == 1 && s[0] == '.')break;

		get_nxt();

		int ans = len % (len - nxt[len]) == 0 ? len / (len - nxt[len]) : 1;
		printf("%d\n", ans);

	}
	return 0;
}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值