kmp的最小循环节

kmp的最小循环节

KMP最小循环节、循环周期:

  • 定理:假设S的长度为len,则S存在最小循环节,循环节的长度L为len-next[len],子串为S[0…len-next[len]-1]。
  • (1)如果len可以被len – next[len]整除,则表明字符串S可以完全由循环节循环组成,循环周期T=len/L。
  • (2)如果不能,说明还需要再添加几个字母才能补全。需要补的个数是循环个数L-len%L=L-(len-L)%L=L-next[len]%L,L=len-next[len]。
  • 理解该定理,首先要理解next数组的含义:next[i]表示前面长度为i的子串中,前缀和后缀相等的最大长度

 

抽象的解释参考这个:https://www.cnblogs.com/wuyiqi/archive/2012/01/06/2314078.html

kmp的最小循环节

k    m   x     j     i

由上,next【i】=j,两段红色的字符串相等(两个字符串完全相等),s[k….j]==s[m….i]

设s[x…j]=s[j….i](xj=ji)

则可得,以下简写字符串表达方式

kj=kx+xj;

mi=mj+ji;

因为xj=ji,所以kx=mj,如下图所示

 k   m     a    x    j     i

设s[a…x]=s[x..j](ax=xj)

又由xj=ji,可知ax=xj=ji

即s[a…i]是由s[a…x]循环3次得来的。

而且看到没,此时又重复上述的模型,s[k…x]=s[m…j],可以一直递推下去

最后可以就可以递推出文章开头所说的定理了。

 

最后再举两个相关例子

abdabdab  len:8 next[8]:5

最小循环节长度:3(即abd)   需要补的个数是1  d

ababa  len:5 next[5]:3

最小循环节长度:2(即ab)    需要补的个数是1  b

下面一道经典例题进行解释

 

 

Power Strings

Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 65955   Accepted: 27243

Description

Given two strings a and b we define a*b to be their concatenation. For example, if a = “abc” and b = “def” then a*b = “abcdef”. If we think of concatenation as multiplication, exponentiation by a non-negative integer is defined in the normal way: a^0 = “” (the empty string) and a^(n+1) = a*(a^n).

Input

Each test case is a line of input representing s, a string of printable characters. The length of s will be at least 1 and will not exceed 1 million characters. A line containing a period follows the last test case.

Output

For each s you should print the largest n such that s = a^n for some string a.

Sample Input

abcd
aaaa
ababab
.

Sample Output

1
4
3
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=1e6+5;;
char str[MAXN];
int _next[MAXN];

void getNext(char *p)
{
    int j,k;
    j=0;
    k=-1;
    int len=strlen(p);
    _next[0]=-1;
    while(j<len)
    {
        if(k==-1||p[j]==p[k])
        {
            j++;
            k++;
            _next[j]=k;
        }
        else k=_next[k];
    }
}
int main()
{
    while(scanf("%s",&str),str[0]!='.')
	{
	    getNext(str);
        int len=strlen(str);//str字符串的个数 
        int t=len-_next[len];//最小循环节 
        if(len%t==0)//原串是否能被循环节整除
		printf("%d\n",len/t);
		else printf("1\n");
    }
    return 0;
}

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/114891.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • executeSql之执行增删改查「建议收藏」

    executeSql之执行增删改查「建议收藏」transaction.executeSql(sqlquery[],dataHandler,errorHandler);第一个参数为需要执行的Sql语句,比如要在表中插入内容executeSql(‘INSERTINTOMsgDataVALUES(?,?,?)'[],dataHandler,errorHandler)VALUES(?,?

  • SIFT算法的应用–目标识别之Bag-of-words模型

    SIFT算法的应用–目标识别之Bag-of-words模型

  • 分布式锁的应用场景和三种实现方式的区别_负载均衡策略

    分布式锁的应用场景和三种实现方式的区别_负载均衡策略多线程对同一资源的竞争,需要用到锁,例如Java自带的Synchronized、ReentrantLock。但只能用于单机系统中,如果涉及到分布式环境(多机器)的资源竞争,则需要分布式锁。分布式锁的主要作用:保证数据的正确性:比如:秒杀的时候防止商品超卖,表单重复提交,接口幂等性。避免重复处理数据:比如:调度任务在多台机器重复执行,缓存过期所有请求都去加载数据库。分布式锁的主要特性:互斥:同一时刻只能有一个线程获得锁。可重入:当一个线程获取锁后,还可以再次获取这个锁,避免死锁发生。高可用:当

  • Linux下编写GT911触摸驱动

    Linux下编写GT911触摸驱动问题一:资源获取Gt911数据手册在韦老师给的资料里,路径为\06_Datasheet\Extend_modules\7寸LCD模块\电容触控芯片GT911Datasheet_121120(海威思.pdf问题二:需要准备哪些知识1.能够修改设备树2.能够编写字符设备驱动3.能够在linux下编写中断程序4.能够在linux下编写IIC收发程序5.了解input子系统6.移植tslib(用于校准,测试触摸屏)gt911硬件连接(韦老师的板子):可以看到gt911只

  • 磁盘在磁盘管理中显示没有初始化找回文件方案「建议收藏」

    磁盘在磁盘管理中显示没有初始化找回文件方案「建议收藏」磁盘没有初始化是因为0号扇区损坏,导致机械硬盘分区表读取不出来,从而机械硬盘出现磁盘没有初始化。工具/软件:极限数据恢复软件步骤1:程序打开后,直接双击需要恢复数据的物理盘。步骤2:等待程序扫描完毕大概需要几分钟到半个小时,稍微耐心等下即可。步骤3:软件扫描到资料后,软件会将扫描到的分区列出来。步骤4:勾上所有需要恢复的资料,右击选择《复制勾选的文件》,…

  • APP安全环节缺失,手游运营商怎样应对APP破解困境

    APP安全环节缺失,手游运营商怎样应对APP破解困境

    2021年11月28日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号