poj 2406 KMP算法
来源:互联网 发布:舌头乐队知乎 编辑:程序博客网 时间:2024/05/15 06:08
题目大意:定义字符串的n次幂为该字符串重复n次并续接起来。例如,假设字符串a="abc",则a^2="abcabc"。要求对每个输入的字符串s,求使s=a^n成立的最大的n。其中a是某个字符串。比如说,对“aaaa”来说,n=4;对于“ababab”,n=3。
题意很明确,就是求一个字符串的最小重复单元的重复次数n。如果一个字符串的最小重复单元是自身,那么n=1。s的最大长度是一百万,可见直接枚举一定会超时。这时可以借助KMP算法中的next数组。
next[i]的大小表示在字符串s的i位置之前,最长有多长的子串与s的前缀相同。应当注意的是,定义中所称的“子串”不能与“s的前缀”相同。举个例子,正如下表所示,字符串s="ababab"所对应的next数组是next[]={-1,0,0,1,2,3,4}。注意,next数组最后一个元素是4而不是6,这正是因为“子串”不能与“s的前缀”相同的缘故。
ababab\0-1001 234怎样从next数组得知最小重复单元的个数呢?从下图可以直观地看出来。
上面图中每个小格代表一个长为m的最小重复单元,整个字符串包括了(L+1)个这样的最小重复单元,所以长度为strlen(s) = (L+1)*m。显然,此字符串对应的next数组的最后一个元素将是next[strlen(s)] = L*m。这样,只要将两者相减即可求得m的大小,即m = strlen(s) - next[strlen(s)]。已知最小重复单元的长度m之后,只要用字符串的长度strlen(s) 除以m即可得到最小重复单元的重复次数。
假如字符串s的最小重复单元就是它自身呢?这种情况等价于strlen(s) 不是(strlen(s) - next[strlen(s)])的倍数。于是只要判断strlen(s) 模(strlen(s) - next[strlen(s)])是否为零即可。
#include <stdio.h>#include <stdlib.h>#include <string.h>#define LOCAL//求一个字符串的最小重复单元的重复次数//m = len-next[len],若len是m的倍数,则m是最小重复单元的长度,len/m是其重复次数//否则str的最小重复单元就是str自身//需要深入理解KMP算法char s[1000009];int next[1000009];void get_next(const char t[],int next[]){ int i = 1,k = 0; next[0] = -1; while(t[i] != '\0') { next[i] = k; if(t[i] == t[k]) { k++; }else if(t[i] != t[0]) { k = 0; }else k = 1; i++; } next[i] = k;}int main(){ int len,m; #ifdef LOCAL if(NULL == freopen("t.txt","r",stdin)) printf("error redirecting\n"); #endif // LOCAL while(1) { scanf("%s",s); if(0 == strcmp(s,".")) break; get_next(s,next); len = strlen(s); m = len - next[len]; if(0 == m) printf("1\n"); else if(0 == len%m) printf("%d\n",len/m); else printf("1\n"); } return 0;}
- poj 2406 KMP算法
- poj 2406 Power Strings kmp算法
- poj 2406 Power Strings kmp算法
- POJ 2406 Power Strings:KMP算法
- poj 2406 Power Strings(kmp算法)
- POJ 2406--Power Strings(kmp算法)
- poj 2406 Power Strings KMP算法
- POJ 2406 KMP算法next数组理解
- POJ 2406 Power Strings(KMP算法)
- POJ 2406 Power Strings KMP算法
- POJ-2406 Power Strings (kmp算法)
- poj 2752 kmp算法
- POJ 3461 KMP算法
- poj 3461 kmp算法
- poj 4468Spy(kmp算法)
- poj 3461 Oulipo KMP算法
- POJ 2185 二维kmp算法
- poj 3461 Oulipo KMP算法
- hdu 1106 排序
- hadoop添加节点和删除节点
- Android系统root破解原理分析
- CString类常用方法----Left(),Mid(),Right()……
- 寻找最长子串,该子串只包含两种字符
- poj 2406 KMP算法
- winrar+计划任务实现文件自动备份
- 堆排序
- 论文参考文献规范格式
- [Oracle] 三种表连接算法总结
- String的+连接操作和StringBuffer的append连接操作差别
- hdu acm 1106
- hadoop集群默认配置和常用配置
- linux学习之linux百问4,awk了解