KMP求字符串最小循环节
证明1:
对于一个字符串S,长度为L,如果由长度为len的字符串s(字符串s的最小循环节是其本身)循环k次构成,那么字符串s就是字符串S的最小循环节
那么字符串有个很重要的性质和KMP挂钩,即 i - next[i] 为字符串s的长度 i%(i - next[i]) ==0
证明:字符串S由s循环k次构成,那么有S[0-->L-len-1] == S[len-->L-1],即前k-1个循环节和后k-1个循环节构成的字符串相等
那么此时KMP数组的next[L] = k-1个循环节的长度, 也即 next[L] = L-len-1+1 = L - len,那么此时 L - next[L] = len , 所以 L % len = 0, L % len = k
所以如果字符串存在循环节,那么i % (i - next[i]) ==0,循环节的长度为 i - next[i]
否则,循环节的为字符串本身。
证明2:
t = n-next[n] 为循环节的长度
1、如果next[n]==0,则表示字符串S前后无任何相同的部分,所以字符串S自身为一个循环节,成立
2、如果next[n]!=0 且 字符串S的循环节个数为2
①:如果字符串S是完美(即每个循环节都是完整的)
那么next[n] = n/2 所以 t = n - next[n] = n/2,成立
②:字符串S的循环节个数为2,但是位于左边的循环节是完整的,右边的是残缺的
那么next[n] = 残缺的循环节和完整的循环节的相似长度,所以t = n - next[n]成立
3、如果next[n]!=0 且字符串S的循环节个数k>=3 ,
那么字符串S从第二个循环节开始到最后一个字符(设长度为len)和字符串S从第一个字符串开始的len个字符相等
所以t = n - next[n]成立
hdu1358
求每一个前缀是不是循环串,如果是,输出串长和循环的次数。
#include <stdio.h>
#include <string.h>
const int N = + ;
char str[N];
int next[N];
void makeNext(char *str)
{
int i=,j=-;
next[] = -;
while(str[i])
{
if(j==-||str[i]==str[j])
{
i++;
j++;
next[i] = j;
}
else
j = next[j];
}
}
int main()
{ int n;
int tCase = ;
while(true)
{
scanf("%d",&n);
if(n==)
break;
scanf("%s",str);
makeNext(str);
printf("Test case #%d\n",tCase++);
for(int i=; i<=n; ++i)
{
if(i%(i-next[i])== && next[i]!=)//next[i]!=0,如果为0,循环节是本身
printf("%d %d\n",i,i/(i-next[i])); }
puts(""); }
return ;
}
hdu3746
补多少个字符能形成循环串
#include <stdio.h>
#include <string.h>
const int N = + ; char str[N];
int next[N]; void makeNext()
{
int i = ,j = -;
next[i] = j;
while(str[i])
{
if(j==- || str[i]==str[j])
next[++i] = ++j;
else
j = next[j];
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%s",str);
int n = strlen(str);
makeNext();
int t = n - next[n];
if(t!=n && n%t==)
puts("");
else
printf("%d\n",t-(n-n/t*t));
}
return ;
}
KMP求字符串最小循环节的更多相关文章
- hdu 4333"Revolving Digits"(KMP求字符串最小循环节+拓展KMP)
传送门 题意: 此题意很好理解,便不在此赘述: 题解: 解题思路:KMP求字符串最小循环节+拓展KMP ①首先,根据KMP求字符串最小循环节的算法求出字符串s的最小循环节的长度,记为 k: ②根据拓展 ...
- KMP模板,最小循环节
(可以转载,但请注明出处!) 下面是有关学习KMP的参考网站 http://blog.csdn.net/yaochunnian/article/details/7059486 http://blog. ...
- HUST 1010 The Minimum Length (字符串最小循环节)
题意 有一个字符串A,一次次的重写A,会得到一个新的字符串AAAAAAAA.....,现在将这个字符串从中切去一部分得到一个字符串B.例如有一个字符串A="abcdefg".,复制 ...
- POJ--2406Power Strings+KMP求字符串最小周期
题目链接:点击进入 事实上就是KMP算法next数组的简单应用.假设我们设这个字符串的最小周期为x 长度为len,那么由next数组的意义,我们知道len-next[len]的值就会等于x.这就是这个 ...
- POJ2406 Power Strings —— KMP or 后缀数组 最小循环节
题目链接:https://vjudge.net/problem/POJ-2406 Power Strings Time Limit: 3000MS Memory Limit: 65536K Tot ...
- hdu3746(kmp最小循环节)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3746 题意:问在一个字符串末尾加上多少个字符能使得这的字符串首尾相连后能够循环 题解:就是利用next ...
- hdu 3746 Cyclic Nacklace(next数组求最小循环节)
题意:给出一串字符串,可以在字符串的开头的结尾添加字符,求添加最少的字符,使这个字符串是循环的(例如:abcab 在结尾添加1个c变为 abcabc 既可). 思路:求出最小循环节,看总长能不能整除. ...
- HDU3746 Cyclic Nacklace —— KMP 最小循环节
题目链接:https://vjudge.net/problem/HDU-3746 Cyclic Nacklace Time Limit: 2000/1000 MS (Java/Others) M ...
- kmp的next数组的运用(求字符串的最小循环节)
hdu3746 Cyclic Nacklace Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/ ...
随机推荐
- Mysql对自增主键ID进行重新排序
Mysql数据库表的自增主键ID号经过一段时间的添加与删除之后乱了,需要重新排列. 原理:删除原有的自增ID,重新建立新的自增ID. 1,删除原有主键: ALTER TABLE `table_name ...
- redis 获取key 过期时间
<pre name="code" class="html">127.0.0.1:6379> keys *b4f107c6-e96c-4a1e- ...
- [置顶] 自己动手写Web容器之TomJetty之六:动态页面引入
传送门 ☞ 1.Web服务内功经脉 传送门 ☞ 2.让服务动起来 传送门 ☞ 3.掀起请求盖头来 传送门 ☞ 4.静态页面起步 传送门 ☞ 5.包装请求参数 在上一节,我们已经完成了TomJetty服 ...
- iOS 开发学习35 本地化
增新语言 打开Project-Info-Localizations 点击Localization下的+ 新增语言 定义多语言文件 新增String Files 在Supporting Files上.新 ...
- Swift - 多行文本输入框(UITextView)的用法
1,多行文本控件的创建 1 2 3 4 var textview=UITextView(frame:CGRectMake(10,100,200,100)) textview.layer.borderW ...
- Gap 锁
14.3.1 InnoDB Locking InnoDB 锁 本章节描述InnoDB 使用的锁类型: Shared and Exclusive Locks Intention Locks Record ...
- 300M无线路由器 TL-WR842N - TP-LINK官方网站
300M无线路由器 TL-WR842N - TP-LINK官方网站 300M无线路由器TL-WR842N 11N无线技术.300Mbps无线速率 2x2MIMO架构.CCA技术,提升无线稳定性.扩大无 ...
- Linux入门基础 #10:命令行文本处理工具
本文出自 http://blog.csdn.net/shuangde800 ------------------------------------------------------------ ...
- POJ 2991 Crane(线段树+计算几何)
POJ 2991 Crane 题目链接 题意:给定一个垂直的挖掘机臂.有n段,如今每次操作能够旋转一个位置,把[s, s + 1]专程a度,每次旋转后要输出第n个位置的坐标 思路:线段树.把每一段当成 ...
- c++实用技巧
原地址:http://www.cnblogs.com/easymind223/articles/2576904.html 晚上的时间总是习惯性的在cnblogs逛街,今天又看到了好文章,其c++味道浓 ...