KMP算法:

一:next数组:next[i]就是前面长度为i的字符串前缀和后缀相等的最大长度,也即索引为i的字符失配时的前缀函数。

二:KMP模板

 /*
pku3461(Oulipo), hdu1711(Number Sequence)
这个模板 字符串是从0开始的
Next数组是从1开始的
*/
#include <iostream>
#include <cstring>
using namespace std; const int maxn = ;
int _next[maxn];
char S[maxn], T[maxn];
int slen, tlen; void getNext()
{
int j, k;
j = ; k = -; _next[] = -;
while(j < tlen)
if(k == - || T[j] == T[k])
_next[++j] = ++k;
else
k = _next[k];
} /*
}
返回模式串T在主串S中首次出现的位置
返回的位置是从0开始的。
*/
int KMP_Index()
{
int i = , j = ;
getNext(); while(i < slen && j < tlen)
{
if(j == - || S[i] == T[j])
{
i++; j++;
}
else
j = _next[j];
}
if(j == tlen)
return i - tlen;
else
return -;
}
/*
返回模式串在主串S中出现的次数
*/
int KMP_Count()
{
int ans = ;
int i, j = ;
if(slen == && tlen == )
{
if(S[] == T[])
return ;
else
return ;
}
getNext();
for(i = ; i < slen; i++)
{
while(j > && S[i] != T[j])
j = _next[j];
if(S[i] == T[j])
j++;
if(j == tlen)
{
ans++;
j = _next[j];
}
}
return ans;
}
int main()
{ int TT;
int i, cc;
cin>>TT;
while(TT--)
{
cin>>S>>T;
slen = strlen(S);
tlen = strlen(T);
cout<<"模式串T在主串S中首次出现的位置是: "<<KMP_Index()<<endl;
cout<<"模式串T在主串S中出现的次数为: "<<KMP_Count()<<endl;
}
return ;
}

三: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]。

学习博客 https://www.cnblogs.com/chenxiwenruo/p/3546457.html

    https://www.cnblogs.com/c-cloud/p/3224788.html

循环节例题

题目链接   https://vjudge.net/problem/UVALive-3026

解析  每个前缀的最小循环节  KMP跑一边判断能不能整除就可以了

AC代码

 #include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define F first
#define S second
#define all(a) (a).begin(), (a).end()
#define fillchar(a, x) memset(a, x, sizeof(a))
#define huan printf("\n");
using namespace std;
typedef long long ll;
const int maxn=1e6+,inf=0x3f3f3f3f;
const ll mod=1e9+;
char p[maxn];
int f[maxn];
int main()
{
int n,kase=;
while(scanf("%d",&n)==&&n)
{
scanf("%s",p);
f[]=,f[]=;
for(int i=;i<n;i++)
{
int j=f[i];
while(j&&p[i]!=p[j]) j=f[j];
f[i+]=(p[i]==p[j]?j+:);
}
printf("Test case #%d\n", ++kase);
for(int i=;i<=n;i++)
{
if(f[i]>&&i%(i-f[i])==)
printf("%d %d\n",i,i/(i-f[i]));
}
huan;
}
}

UVAlive 3026 KMP 最小循环节的更多相关文章

  1. Cyclic Nacklace hdu3746 kmp 最小循环节

    题意:给出一段字符串  求最少在最右边补上多少个字符使得形成循环串(单个字符不是循环串) 自己乱搞居然搞出来了... 想法是:  如果nex[len]为0  那么答案显然是补len 否则  答案为循环 ...

  2. HDU1358 Period —— KMP 最小循环节

    题目链接:https://vjudge.net/problem/HDU-1358 Period Time Limit: 2000/1000 MS (Java/Others)    Memory Lim ...

  3. Common Divisors CodeForces - 182D || kmp最小循环节

    Common Divisors CodeForces - 182D 思路:用kmp求next数组的方法求出两个字符串的最小循环节长度(http://blog.csdn.net/acraz/articl ...

  4. HDU - 4333 Revolving Digits(拓展kmp+最小循环节)

    1.给一个数字字符串s,可以把它的最后一个字符放到最前面变为另一个数字,直到又变为原来的s.求这个过程中比原来的数字小的.相等的.大的数字各有多少. 例如:字符串123,变换过程:123 -> ...

  5. 【KMP+最小循环节】F. Cyclic Nacklace

    https://www.bnuoj.com/v3/contest_show.php?cid=9147#problem/F [题意] 给定一个字符串,问在字符串后最少添加多少个字母,得到的新字符串能是前 ...

  6. [poj 2185] Milking Grid 解题报告(KMP+最小循环节)

    题目链接:http://poj.org/problem?id=2185 题目: Description Every morning when they are milked, the Farmer J ...

  7. hdu3746(kmp最小循环节)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3746 题意:问在一个字符串末尾加上多少个字符能使得这的字符串首尾相连后能够循环 题解:就是利用next ...

  8. HDU 6740 kmp最小循环节

    题意:给一个无线循环小数的前几位,给n,m 选择其中一种出现在前几位的循环节方式(a个数),循环节的长度b 使得n*a-m*b最大 样例: 2 1 12.1212 输出 6 选择2,2*1-1*1=1 ...

  9. hdu 3746 Cyclic Nacklace(kmp最小循环节)

    Problem Description CC always becomes very depressed at the end of this month, he has checked his cr ...

随机推荐

  1. react基础语法(三)组件的创建和复合组件

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. 【Conclusion】MySQL的安装和使用

    MySQL使用 因为数据库实验用到了MySQL,这里对现在已经涉及到的MySQL部分操作做一个简单的小结. 1.安装MySQL 上MySQL的官网下载对应自己OS平台的MySQL安装文件,有在线安装和 ...

  3. gitee 如何创建仓库 及发布

    gitee 如何创建仓库 及发布 http://pengchenggang.gitee.io/layuisyshelp ----------- 在本地项目文件中使用bash $ git config ...

  4. QT_4_QpushButton的简单使用_对象树

    QpushButton的简单使用 1.1 按钮的创建 QPushButton *btn = new QPushButton; 1.2 btn -> setParent(this);设置父窗口 1 ...

  5. 【软件构造】第八章第三节 代码调优的设计模式和I/O

    第八章第三节 代码调优的设计模式和I/O 本节学习如何通过对代码的修改,消除性能瓶颈,提高系统性能?——代码调优.面向性 能的设计模式 Outline Java调优 代码调优的概念 单例模式(Sing ...

  6. 两个乒乓球队进行比赛,各出三人。 甲队为a,b,c三人,乙队为x,y,z三人。 已抽签决定比赛名单。 有人向队员打听比赛的名单。 a说他不和x比,c说他不和x,z比, 请编程序找出三队赛手的名单。

    题目:两个乒乓球队进行比赛,各出三人. 甲队为a,b,c三人,乙队为x,y,z三人. 已抽签决定比赛名单. 有人向队员打听比赛的名单. a说他不和x比,c说他不和x,z比, 请编程序找出三队赛手的名单 ...

  7. AspNetCore容器化(Docker)部署(一) —— 入门

    一.docker注册安装 Windows Docker Desktop https://www.docker.com/products/docker-desktop Linux Docker CE h ...

  8. python 一些函数和类用法记录

    这一篇主要用来记录在学习过程中遇到的一些觉得有意思的函数或者类的用法,有一些用法感觉很炫酷. 1.collections.defaultdict from collections import def ...

  9. bzoj 1098 [POI2007] 办公楼 biu

    # 解题思路 画画图可以发现,只要是两个点之间没有相互连边,那么就必须将这两个人安排到同一个办公楼内,如图所示: 那,我们可以建立补图,就是先建一张完全图,然后把题目中给出的边都删掉,这就是一张补图, ...

  10. luogu 1608 路径统计--最短路计数

    https://www.luogu.org/problemnew/show/P1608 题意https://www.cnblogs.com/rmy020718/p/9440588.html相似,建议还 ...