KMP算法的练习题(poj 3461、poj 2752、poj 2406、poj 1961)
2012-03-15 22:38
447 查看
//poj 3461 Oulipo 最简单的KMP题,找出第一个字符串在第二个字符串中出现次数。 #include<stdio.h> #define M 1000010 char s[M],t[M]; int next[M],sum; void getNext()//求next数组 { int i,j; next[0]=-1; for(i=1,j=-1;s[i];i++){ while(j!=-1&&s[i]!=s[j+1])j=next[j];//从s[j+1]开始找与s[i]相同的字母 if(s[j+1]==s[i])j++; next[i]=j;//如果找到相同字母,next[i]记录此位置,否则next[i]=next[i-1] } } void kmp() { int i,j; sum=0; getNext(); for(i=0,j=-1;t[i];i++){ while(j!=-1&&s[j+1]!=t[i])j=next[j];//按next[j]后退找出与t[i]相同的s[j+1] if(s[j+1]==t[i])j++;//如果找到则向后前进 if(!s[j+1]){//如果在t中找到完整的s sum++;//计数增1 j=next[j];//按next后退 } } } int main() { int T; scanf("%d",&T); while(T--){ scanf("%s%s",s,t); kmp(); printf("%d\n",sum); } return 0; } //poj 2752 Seek the Name, Seek the Fame 求子串前缀跟后缀一样的各种情况 #include<stdio.h> #include<string.h> #define M 400010 int j,n,res[M],next[M]; char s[M]; void getNext() { int i=1; next[0]=-1; for(j=-1;s[i];i++){ while(j!=-1&&s[j+1]!=s[i])j=next[j]; if(s[j+1]==s[i])j++; next[i]=j; } n=i; } int main() { int i,num; while(~scanf("%s",s)){ getNext(); j=n-1; num=0; while(j!=-1){ res[++num]=j+1; j=next[j]; } for(i=num;i>0;i--)printf("%d ",res[i]); puts(""); } return 0; } //poj 2406 Power Strings求子串在主串中最多叠加次数 #include<stdio.h> #define M 1000010 int n,next[M]; char s[M]; void getNext() { int i=1,j=-1; next[0]=-1; for(;s[i];i++){ while(j!=-1&&s[j+1]!=s[i])j=next[j]; if(s[j+1]==s[i])j++; next[i]=j; } n=i; } int main() { while(scanf("%s",s),s[0]!='.'){ getNext(); if(n%(n-next[n-1]-1))puts("1"); else printf("%d\n",n/(n-next[n-1]-1)); } return 0; } //poj 1961 Period 跟上面一题几乎一样,把主串的每一种前缀当作小主串,如果小主串的子串在小主串中叠加次数大于1,输出小主串长度及叠加次数。 #include<stdio.h> #define M 1000010 int i,n,next[M]; char s[M]; void getNext() { int j=-1; next[0]=-1; for(i=1;s[i];i++){ while(j!=-1&&s[j+1]!=s[i])j=next[j]; if(s[j+1]==s[i])j++; next[i]=j; } } int main() { int k=0; while(scanf("%d",&n),n){ scanf("%s",s); printf("Test case #%d\n",++k); getNext(); for(i=1;i<=n;i++) if(i%(i-next[i-1]-1)==0&&next[i-1]>-1) printf("%d %d\n",i,i/(i-next[i-1]-1)); puts(""); } return 0; }
参考资料:
http://blog.sina.com.cn/s/blog_69c3f0410100txk7.html
相关文章推荐
- KMP入门题 Hdu 1711 2594 3746 HUST 1010 Poj 3461 2752 2406 1961 FZU 1901
- KMP算法的经典例题(poj 3461、poj 2752、poj 2406、poj1961)
- POJ 2752、2406、1961 KMP的next[](或p[])简单应用
- POJ 2406/ POJ 1961/ POJ 2752——几个相似的简单KMP问题
- POJ 1961/POJ 2406 /POJ 2752 /【KMP应用】
- POJ 3461和COJ 1248 KMP算法
- poj 2406 kmp算法巩固之next数组的再理解
- kmp算法练习 poj 1226 poj 1961
- POJ 2752 Seek the Name, Seek the Fame kmp算法
- POJ-2406 Power Strings (kmp算法)
- POJ 1961 Period KMP算法之next数组的应用
- poj 2406 poj 1961 个人对吉大KMP模板的理解 KMP 基础题--找周期串
- POJ 3461 Oulipo KMP算法题解
- POJ 3461 Oulipo(——KMP算法)
- POJ-1961 Period (kmp算法)
- POJ 2406 Power Strings(KMP算法)
- LA 3026 && POJ 1961 Period (KMP算法)
- POJ 1961 Period KMP算法next数组的应用
- POJ 3461 Oulipo 深刻理解KMP算法next数组含义
- POJ-3461 Oulipo-匹配的字符有几个(KMP算法)