KMP
2015-10-05 19:01
197 查看
// hdu 1358前缀是由几个循环串组成 next数组的运用 next[i]数组是后缀与前缀的最大相匹配的字符个数 #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #include<vector> using namespace std; typedef long long ll; typedef pair<int,int> pp; #define inf 0x3f3f3f3f #define eps 1e-10 #define maxl 1000010 #define mem(i,j) memset(i,j,sizeof(i)) const int mod=1e9+7; char s[maxl]; int n,jump[maxl]; void get_next(){ jump[1]=0; int k=0; for(int i=2;i<=n;i++){ while(k>0&&s[k+1]!=s[i]) k=jump[k]; if(s[k+1]==s[i]) k+=1; jump[i]=k; } } int main() { freopen("in.txt", "r", stdin); int t=0; while(scanf("%d",&n)&&n){ printf("Test case #%d\n",++t); scanf("%s",s+1); get_next(); for(int i=2;i<=n;i++){ if(jump[i]&&i%(i-jump[i])==0){ printf("%d %d\n",i,i/(i-jump[i])); } } printf("\n"); } }
//P UVA 11475 补全字符串 使得这个是回文字符串 但是补的字符最少 这是暴力的做法 KMP的还有待学习
/*
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<int,int> pp;
#define inf 0x3f3f3f3f
#define eps 1e-10
#define maxl 1000010
#define mem(i,j) memset(i,j,sizeof(i))
const int mod=1e9+7;
char s[maxl];
int main()
{
freopen("in.txt", "r", stdin);
while(gets(s)){
int len=strlen(s);
for(int i=0;i<len;i++){
int l=i,r=len-1;
int flag=1;
for(int j=0;j<=(r-l+1)/2;j++) if(s[l+j]!=s[r-j]) {flag=0;break;}
if(flag){
printf("%s",s);
for(int j=i-1;j>=0;j--) printf("%c",s[j]);
printf("\n");
break;
}
}
}
}
*/
//O UVA 12886二维的KMP 但是只有黑白俩种 hash 小矩形和大矩形 <=2000 hash打法 可以处理的情况很大的时候 #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #include<vector> using namespace std; typedef unsigned long long ll; typedef pair<int,int> pp; #define inf 0x3f3f3f3f #define eps 1e-10 #define maxl 2020 #define mem(i,j) memset(i,j,sizeof(i)) const int mod=1e9+7; const ll seed1=10000007; const ll seed2=100000007; char s1[maxl][maxl],s2[maxl][maxl]; ll hash1[maxl][maxl],hash2[maxl][maxl],h; int x,y,n,m,ans; ll get_hash(){ //预处理小矩形 ll cnt=0,res; for(int i=0;i<x;i++){ res=0; for(int j=0;j<y;j++) res=res*seed1+s1[i][j];//处理行 cnt=cnt*seed2+res;//处理列 } return cnt; } void solve(){ ans=0; ll c=1; for(int i=0;i<y;i++) c=c*seed1;//这个是hash种子 y次seed1 for(int i=0;i<n;i++){ ll res=0; for(int j=0;j<y;j++) //这里的0是y-1次seed1 刚好对应下面的 res=res*seed1+s2[i][j];//处理相同长度的目标矩形的行 hash1[i][y-1]=res;//用hash1来保存 for(int j=y;j<m;j++){ hash1[i][j]=hash1[i][j-1]*seed1-s2[i][j-y]*c+s2[i][j];//用DP的思想 来递归 } } c=1; for(int i=0;i<x;i++) c=c*seed2; for(int i=y-1;i<m;i++){ ll cnt=0; for(int j=0;j<x;j++) cnt=cnt*seed2+hash1[j][i]; if(cnt==h) ans++; hash2[x-1][i]=cnt; for(int j=x;j<n;j++){ hash2[j][i]=hash2[j-1][i]*seed2-hash1[j-x][i]*c+hash1[j][i]; if(hash2[j][i]==h) ans++; } } } int main() { freopen("in.txt", "r", stdin); while(scanf("%d%d%d%d",&x,&y,&n,&m)!=EOF){ memset(hash1,0,sizeof(hash1)); memset(hash2,0,sizeof(hash2)); for(int i=0;i<x;i++) scanf("%s",s1[i]); for(int i=0;i<n;i++) scanf("%s",s2[i]); h=get_hash(); solve(); printf("%d\n",ans); } }
相关文章推荐
- DOM编程--属性操作
- hdu Beauty of Sequence (好题_集合问题)
- Linux的硬链接和软连接(符号连接)
- C语言的谜题
- static_cast转换类型输出
- static 使用之静态初始化块
- 远程调试hadoop各组件
- 源代码制作成RPM包
- eclipse插件手动安装(link)
- 校验码检验
- 探讨LoadRunner的并发用户和集合点
- 弹性布局各种坑爹兼容
- android-线程 (从java开始)案例
- 使用zookeeper管理多个hbase集群
- 让你快速认识flume及安装和使用flume1.5传输数据(日志)到hadoop2.2
- SPOJ BALNUM Balanced Numbers 平衡数(数位DP,状压)
- 对称与非对称加密
- 动态代理
- 常用监控命令总结
- 大话设计模式C++达到-文章16章-国家模式