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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • chmod 命令——chmod 755与 chmod 4755区别

    chmod 命令——chmod 755与 chmod 4755区别755和4755的区别chmod是Linux下设置文件权限的命令,后面的数字表示不同用户或用户组的权限。一般是三个数字:第一个数字表示文件所有者的权限第二个数字表示与文件所有者同属一个用户组的其他用户的权限第三个数字表示其它用户…

    2022年7月16日
    15
  • linux如何卸载eclipse(eclipse工具linux版本)

    1.安装JDK6先确认已经添加了软件源,在系统-系统管理-软件源-其它软件,确保已经选中http://archive.canonical.com/ubuntulucidpartner这个源。sudoapt-getinstallsun-java6-jdk设置系统环境变量exportJAVA_HOME=/usr/lib/jvm/java-6-sun(根据具体的安装路径)expor…

    2022年4月17日
    89
  • Flash Builder 4.5 导入一个新项目,提示“flex unable to open xxxxxxxxx.swc”

    Flash Builder 4.5 导入一个新项目,提示“flex unable to open xxxxxxxxx.swc”参考http://forums.adobe.com/thread/741783http://forums.esri.com/Thread.asp?c=158&f=2421&t=297291 1、如果提示FLEXSDKX.X找不到,就下载这个SDK,然后再WINDOWS/PREFERENCE里面吧SDK配置好路径2、提示“flexunabletoopenxxxxxxx

    2022年8月22日
    11
  • Spark1.0.0 开发环境高速搭建

    Spark1.0.0 开发环境高速搭建

    2022年2月5日
    49
  • 微信小程序开发之(表单组件的使用)代码篇

    微信小程序开发之(表单组件的使用)代码篇目录1.工程目录2.代码3.结果6.获取资源这篇文章介绍微信小程序的表单组件的使用1.工程目录需要改动的文件上图已经标出来了2.代码index.js//index.js//获取应用实例constapp=getApp()Page({onShareAppMessage(){return{title:’cover-view’,path:’page/component/pages/cover-view/cover-view

    2022年7月15日
    21
  • mvc与三层结构终极区别[通俗易懂]

    mvc与三层结构终极区别[通俗易懂]注:本文章内所有内容都来自互联网,本人主要是起了一个收集的作用http://www.cnblogs.com/zhhh/archive/2011/06/10/2077519.html又看到有人在问三层架构和MVC的关系,感觉这种问题有点教条化了。因为它们都在逻辑上将应用程序划为三块,凑了一个数字3,就有人非要把它们联系到一起了。  这两个东西我接触有几年了,有一点体会,表达一下:

    2022年6月25日
    20

发表回复

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

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