POJ 2406 Power Strings(KMP求最小循环节)
2015-08-14 16:20
357 查看
先简单介绍一下KMP算法利用 nxt 数组求最小循环节的原理:
![](http://img.blog.csdn.net/20150814161248422?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
假设图中的黑色是原来的字符串,现在要求最小循环节,对于nxt[len]来说指的是图中蓝色和黄色的长度,而且蓝色和黄色是相等的,
那么绿色和紫色也是相等的,,对比原串可知紫色跟粉色是相同的子串,那么绿色跟粉色相同,然后对比蓝色跟黄色可知红色跟粉色相同,对比原串,红色跟棕色相同,那么棕色跟粉色相同,不断重复此过程可知若此字符串有最小循环节,那么循环次数一定为len/(len-nxt[len])。
结论:如果len%(len-nxt[len])=0,那么循环次数为len/(len-nxt[len]),否则为1
假设图中的黑色是原来的字符串,现在要求最小循环节,对于nxt[len]来说指的是图中蓝色和黄色的长度,而且蓝色和黄色是相等的,
那么绿色和紫色也是相等的,,对比原串可知紫色跟粉色是相同的子串,那么绿色跟粉色相同,然后对比蓝色跟黄色可知红色跟粉色相同,对比原串,红色跟棕色相同,那么棕色跟粉色相同,不断重复此过程可知若此字符串有最小循环节,那么循环次数一定为len/(len-nxt[len])。
结论:如果len%(len-nxt[len])=0,那么循环次数为len/(len-nxt[len]),否则为1
#pragma warning(disable:4996) #include <cstdio> #include <cstring> using namespace std; char s[1000100]; int nxt[1000100]; void get_nxt(){ int len = strlen(s); nxt[0] = -1; int i = 0, j = -1; while (i < len){ if (j == -1 || s[i] == s[j]){ i++, j++; nxt[i] = j; } else j = nxt[j]; } } int main(){ //freopen("in.txt", "r", stdin); while (scanf("%s", s)){ int len = strlen(s); if (len == 1 && s[0] == '.')break; get_nxt(); int ans = len % (len - nxt[len]) == 0 ? len / (len - nxt[len]) : 1; printf("%d\n", ans); } return 0; }
相关文章推荐
- 使用cxf发布webservice总结
- multi thread
- hdu 5384 Danganronpa
- Eclipse 用maven构建web项目
- hdu 5375 - Gray code(dp) 解题报告
- FHS 标准的文件系统的目录结构
- c#异步调用和回调
- css三角的做法
- 【锋利的jQuery】学习笔记02
- 二分查找(JAVA)
- 判断IP地址,MAC地址合法性-C语言
- Triangle LOVE 4324 (拓扑排序)
- 二三十万汽车选型指南
- Ivshmem实现分析与性能测试
- 关于在header里增加参数的方式
- 微信支付过程中遇到的问题
- Android Fragment 你应该知道的一切
- 设计模式:观察者模式
- BZOJ 1212 HNOI2004 L语言 AC自己主动机(Trie树)+动态规划
- 【ASP.NET开发】获取客户端IP地址 via C#