KMP算法模板及问题解决(HDU 1711)(hihocoder 1015 KMP)(HDU 1686)(POJ3461)(HDU1358)
2016-05-03 22:09
465 查看
博大精深的KMP,我要开始搞你了!
首先,了解KMP算法,KMP是一种改进了的字符串算法,用于优化匹配字符串的。
至于具体内容,本人还是讲不出来的,见几种好的讲解。KMP KMP理解 KMP算法
具体问题,HDU1711:
模板代码如下:
hihocoder1015
HDU1686(代码相同)
POJ3461
HDU1358
对于KMP还是没有理解啊,这个题又是看的别人的题解才做出来的。
Next[i+1]+1 也可代表 i+1 之前的循环串的长度,所以用 i - (Next[i+1]-1) 可以代表剩下的长度,那么我们就可以用 i - (Next[i+1]-1) 是否是i的因子,如果是的话那么循环就出来了。注意Next[i]的使用
首先,了解KMP算法,KMP是一种改进了的字符串算法,用于优化匹配字符串的。
至于具体内容,本人还是讲不出来的,见几种好的讲解。KMP KMP理解 KMP算法
具体问题,HDU1711:
模板代码如下:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N = 1000005; int s ,p ,Next ;//此处有“巨坑”,next是在iostream中已定义的,不能用,用的话去掉iostream头文件 void Getfail(int m)//next不能用 { Next[0]=-1; int i=0,j=-1; while(i<m) { if(j==-1||p[i]==p[j])//匹配 { i++,j++; Next[i]=j; } else j=Next[j]; } } int KMP(int n,int m) { int i=0,j=0; while(i<n) { if(j==-1||s[i]==p[j]) i++,j++; else j=Next[j]; if(j==m) return i-j+1; } return -1; } int main() { int t,n,m; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(int i=0;i<n;i++) scanf("%d",&s[i]); for(int i=0;i<m;i++) scanf("%d",&p[i]); Getfail(m); printf("%d\n",KMP(n,m)); } return 0; }
hihocoder1015
HDU1686(代码相同)
POJ3461
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N = 1000005; char s ,p ; int Next ;//此处有“巨坑”,next是在iostream中已定义的,不能用,用的话去掉iostream头文件 void Getfail(int m) { Next[0]=-1; int i=0,j=-1; while(i<m) { if(j==-1||p[i]==p[j])//匹配 { i++,j++; Next[i]=j; } else j=Next[j]; } } int KMP(int n,int m) { int i=0,j=0,ans=0; while(i<n) { if(j==-1) { i++,j++; } if(s[i]==p[j]) { if(j==m-1) { ans++; j=Next[j]; } else { i++,j++; } } else j=Next[j]; } return ans; } int main() { int t,n,m; scanf("%d",&t); while(t--) { scanf("%s%s",p,s); m=strlen(p);//要用来匹配的字符串 n=strlen(s);//主字符串 Getfail(m); printf("%d\n",KMP(n,m)); } return 0; }
HDU1358
对于KMP还是没有理解啊,这个题又是看的别人的题解才做出来的。
Next[i+1]+1 也可代表 i+1 之前的循环串的长度,所以用 i - (Next[i+1]-1) 可以代表剩下的长度,那么我们就可以用 i - (Next[i+1]-1) 是否是i的因子,如果是的话那么循环就出来了。注意Next[i]的使用
#include<iostream> #include<cstdio> using namespace std; const int N = 1000005; char s ; int n,Next ; void Getfail() { Next[1]=0; int i=1,j=0; while(i<=n) { if(j==0||s[i]==s[j]) { i++,j++; Next[i]=j; } else j=Next[j]; } } int main() { int t=0,k; while(~scanf("%d",&n)&&n) { scanf("%s",s+1); Getfail(); printf("Test case #%d\n",++t); for(int i=2;i<=n;i++) { k = i - (Next[i+1]-1); if(i!=k&&i%k==0) printf("%d %d\n",i,i/k); } printf("\n"); } return 0; }
相关文章推荐
- jquery中动画特效方法
- 时间戳转换
- 【HUSTOJ】1026: 判断素数
- RGB vs YCbCr(YUV)
- 数组和链表的区别
- Java Web 错误/异常处理页面
- iOS编译FFmpeg、kxmovie实现视频播放
- 80. Remove Duplicates from Sorted Array II
- 子数组和最接近零问题
- 移植u-boot到mini2440--用openjtag加载
- Ubuntu下使用genymotion
- C++基础实例-文件Io等(5)
- linux基本命令(12)——more命令
- awk 随机数函数
- Centos下重要日志文件及查看方式
- C/C++头文件一览
- vs发布的程序不依赖运行时库msvcp100.dll
- 测试SMS发送
- location.href
- joomla网站上传