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;
}

 

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

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

(0)
上一篇 2021年9月27日 下午8:00
下一篇 2021年9月27日 下午9:00


相关推荐

  • 如何打开sln文件并显示窗口_在.sln文件中设置Visual Studio默认启动项目的简单方法…[通俗易懂]

    如何打开sln文件并显示窗口_在.sln文件中设置Visual Studio默认启动项目的简单方法…[通俗易懂]昨天在一台电脑上用git新签出一个项目进行build,却出现一堆编译错误,而在原先的开发机上build无任何错误。对比分析后发现,开发机上VS的启动项目(startupproject)与这台电脑上的不一样,改为一样后,build立马成功。看来问题与msbuild编译VS项目的顺序有关,而哪个项目作为启动项目会影响到这个编译顺序。要避免这个问题,就要保证git签出的VS解决方案的启动项目是一致的,…

    2022年6月9日
    92
  • sunlime 激活码(最新序列号破解)

    sunlime 激活码(最新序列号破解),https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月20日
    56
  • CocosCreator 制作微信小游戏排行榜,超越好友,分享功能

    CocosCreator 制作微信小游戏排行榜,超越好友,分享功能在每局游戏结束时 用来显示玩家在好友中的排行 这个需要在微信提供的开放数据域中完成 微信为防止数据外泄 特地提供了开放数据域 开发者只能在子域获取数据 不能上传到外部 微信开放数据域中计算好排行榜数据 并显示 渲染到主域的页面上 需要在主域画布下 创建一个和画布大小相同的空物体 挂载组件子域的画面就是通过该组件渲染到挂载该组件的物体上 有点类似 Unity 的 RawIm

    2026年3月16日
    2
  • Java作业2.0

    Java作业2.0设计一个用户类User,类中的变量有用户名、密码和记录用户数量的变量,定义3个构造方法:无参的、为用户名赋值的、为用户名和密码赋值的,还有获取和设置密码的方法和返回类信息的方法。packageJa

    2022年7月2日
    31
  • android酒店点餐系统设计,基于安卓Android酒店点餐系统APP的设计与实现(MySQL)(含录像)…

    android酒店点餐系统设计,基于安卓Android酒店点餐系统APP的设计与实现(MySQL)(含录像)…基于安卓Android酒店点餐系统APP的设计与实现(MySQL)(含录像)(毕业论文9900字,程序代码,Android客户端和JAVA服务端,MySQL数据库)系统需求分析手机端:1.用户注册、登录、修改密码、修改个人信息2.查看菜单、加入菜单列表,选择日期,模拟在线支付或者餐后付款3.查看个人订单,用餐评论后台管理端:1.管理员登录、修改密码2.酒店菜…

    2022年6月19日
    42
  • c语言 switch case 字符串,c语言switch case用法详解

    c语言 switch case 字符串,c语言switch case用法详解c 语言 switchcase 用法详解 switch 是 开关 的意思 它也是一种 选择 语句 但它的用法非常简单 switch 是多分支选择语句 说得通俗点 多分支就是多个 if 推荐学习 c 语言视频教程从功能上说 switch 语句和 if 语句完全可以相互取代 但从编程的角度 它们又各有各的特点 所以至今为止也不能说谁可以完全取代谁 当嵌套的 if 比较少时 三个以内 用 if 编写程序会比较简洁 但是当选择的分支

    2026年3月26日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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