OJ笔记 18940 最小循环节(KMP算法)

18940 最小循环节(KMP算法)

Description
给定一个字符串,请计算这个字符串最多是由多少个相同的子字符串重复连接而成的。
如:acacac 最多有 3 个 ac 连接而成,bbbb最多由4个b连接而成,abc最多由1个abc连接而成。
此问题需求出整个字符串的最大相同真前后缀,需使用kmp算法或字符串哈希法,具体解释可看下图或百度最小循环节。
在这里插入图片描述
输入格式
一个字符串,长度不超过100000。

输出格式
组成字符串的最多重复连接子串的个数。

输入样例
ababab

输出样例
3

解题思路:
求next数组,最大相同前后缀长度p = next[len]

#include <iostream>
#include <string.h>
#include <cstdio>

using namespace std;

char s[1000001];
int Next[1000001] = {0};
int len,p;//p:整个字符串最大相同前缀的长度

//定义模式串s的next函数值并存入数组next
void getNext()
{
    //注意字符串是从下标1开始录入,下标0用来存放长度
    int k = 0;
    Next[1] = 0;//初始化也是初始化下标为1的next
    for(int i = 2;i <=len;i++){ //i是字符串的下标,k是next的下标
        while(k && s[k+1] != s[i])  k=Next[k];
        if(s[k + 1] == s[i]){ //k这里有下标和当前next的值两个意思
            k++;
            Next[i] = k;
        }
    }
}

int main()
{
    scanf("%s",s + 1);//字符串从第二位输入(s[1]开始)//相当于cin >> s+1;
    len = strlen(s+1);
    getNext();
    p = Next[len];//p长度
    int m = len - p;
    if(len % m == 0){ //[1,m]和[m+1,2m]相同,同理得整个字符串为长度为m的循环子串获得的
        //循环次数
        int ans = len / m;
        cout << ans << endl;
    }
    else{
        cout << "1" << endl;
    }

    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值