邝斌的ACM模板(KMP算法)
来源:互联网 发布:java字符串转换为数组 编辑:程序博客网 时间:2024/06/05 18:47
本博客整理自邝斌的ACM模板
1.1、KMP 算法
/** next[]的含义:x[i-next[i]...i-1]=x[0...next[i]-1]* next[i]为满足x[i-z...i-1]=x[0...z-1]的最大z值(就是x的自身匹配)*/void kmp_pre(char x[],int m,int next[]){ int i,j; j=next[0]=-1; i=0; while(i<m) { while(-1!=j && x[i]!=x[j])j=next[j]; next[++i]=++j; }}/** kmpNext[]的意思:next'[i]=next[next[...[next[i]]]] (直到next'[i]<0或者 x[next'[i]]!=x[i])* 这样的预处理可以快一些 */void preKMP(char x[],int m,int kmpNext[]){ int i,j; j=kmpNext[0]=-1; i=0; while(i<m) { while(-1!=j && x[i]!=x[j])j=kmpNext[j]; if(x[++i]==x[++j])kmpNext[i]=kmpNext[j]; else kmpNext[i]=j; }}/** 返回x在y中出现的次数,可以重叠 */int next[10010];int KMP_Count(char x[],int m,char y[],int n){ //x是模式串,y是主串 int i,j; int ans=0; //preKMP(x,m,next); kmp_pre(x,m,next); i=j=0; while(i<n) { while(-1!=j && y[i]!=x[j])j=next[j]; i++; j++; if(j>=m) { ans++; j=next[j]; } } return ans;}
经典题目:POJ 3167
/** POJ 3167 Cow Patterns* 模式串可以浮动的模式匹配问题 * 给出模式串的相对大小,需要找出模式串匹配次数和位置 * 比如说模式串:1,4,4,2,3,1 而主串:5,6,2,10,10,7,3,2,9 * 那么2,10,10,7,3,2就是匹配的 * * 统计比当前数小,和于当前数相等的,然后进行kmp */#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>#include <vector>using namespace std;const int MAXN=100010;const int MAXM=25010;int a[MAXN];int b[MAXN];int n,m,s;int as[MAXN][30];int bs[MAXM][30];void init(){ for(int i=0; i<n; i++) { if(i==0) { for(int j=1; j<=25; j++)as[i][j]=0; } else { for(int j=1; j<=25; j++)as[i][j]=as[i-1][j]; } as[i][a[i]]++; } for(int i=0; i<m; i++) { if(i==0) { for(int j=1; j<=25; j++)bs[i][j]=0; } else { for(int j=1; j<=25; j++)bs[i][j]=bs[i-1][j]; } bs[i][b[i]]++; }}int next[MAXM];void kmp_pre(){ int i,j; j=next[0]=-1; i=0; while(i<m) { int t11=0,t12=0,t21=0,t22=0; for(int k=1; k<b[i]; k++) { if(i-j>0)t11+=bs[i][k]-bs[i-j-1][k]; else t11+=bs[i][k]; } if(i-j>0)t12=bs[i][b[i]]-bs[i-j-1][b[i]]; else t12=bs[i][b[i]]; for(int k=1; k<b[j]; k++) { t21+=bs[j][k]; } t22=bs[j][b[j]]; if(j==-1 || (t11==t21&&t12==t22)) { next[++i]=++j; } else j=next[j]; }}vector<int>ans;void kmp(){ ans.clear(); int i,j; kmp_pre(); i=j=0; while(i<n) { int t11=0,t12=0,t21=0,t22=0; for(int k=1; k<a[i]; k++) { if(i-j>0)t11+=as[i][k]-as[i-j-1][k]; else t11+=as[i][k]; } if(i-j>0)t12=as[i][a[i]]-as[i-j-1][a[i]]; else t12=as[i][a[i]]; for(int k=1; k<b[j]; k++) { t21+=bs[j][k]; } t22=bs[j][b[j]]; if(j==-1 || (t11==t21&&t12==t22)) { i++; j++; if(j>=m) { ans.push_back(i-m+1); j=next[j]; } } else j=next[j]; }}int main(){ while(scanf("%d%d%d",&n,&m,&s)==3) { for(int i=0; i<n; i++) { scanf("%d",&a[i]); } for(int i=0; i<m; i++) { scanf("%d",&b[i]); } init(); kmp(); printf("%d\n",ans.size()); for(int i=0; i<ans.size(); i++) printf("%d\n",ans[i]); } return 0;}
阅读全文
1 0
- 邝斌的ACM模板(KMP算法)
- 邝斌的ACM模板(扩展 KMP)
- ACM模板——KMP算法
- KMP算法(模板)
- 邝斌的ACM模板(素数)
- 邝斌的ACM模板(求逆元)
- 邝斌的ACM模板(FFT)
- 邝斌的ACM模板(RMQ )
- 邝斌的ACM模板(树链剖分)
- 【KMP】KMP算法模板
- KMP算法(各种模板)
- ACM #1015 KMP算法
- acm-kmp算法
- ACM算法模板 · 一些常用的算法模板-模板合集(打比赛专用)
- ACM算法模板 · 一些常用的算法模板-模板合集(打比赛专用)
- 串的模式匹配KMP算法模板
- KMP算法的几种模板
- 邝斌的ACM模板(扩展欧几里得算法(求 ax+by=gcd 的解以及逆元素))
- SElinux
- .NET读取视频信息、视频截图
- SOAP和WSDL的一些必要知识
- STM8S103之tim2捕获周期
- SVM入门(九)松弛变量(续)
- 邝斌的ACM模板(KMP算法)
- Java类和对象 详解(一)
- 有个对象已经锁了,调用这个对象的方法会被阻塞吗?
- 【其他】去掉Coding Pages的欢迎页之Hosted by Coding Pages,我的是Hexo的Next主题
- Netty 实战
- tensor2tensor
- SVM入门(十)将SVM用于多类分类
- 关于input输入框type为number型时 maxlength无效解决办法
- HDU6098 Inversion