算法笔记--KMP算法 && EXKMP算法
1.KMP算法
这个博客写的不错:http://www.cnblogs.com/SYCstudio/p/7194315.html
模板:
next数组的求解,那个循环本质就是如果相同前后缀不能加上该位置成就该位置的next数组就一直找相同前后缀的相同前后缀。
求解前缀数组F(也叫next数组):
- for (int i=;i<m;i++)
- {
- int j=F[i-];
- while ((B[j+]!=B[i])&&(j>=))
- j=F[j];
- if (B[j+]==B[i])
- F[i]=j+;
- else
- F[i]=-;
- }
利用F数组寻找匹配,这里我们是每找到一个匹配就输出其开始的位置:
- while (i<n)
- {
- if (A[i]==B[j])
- {
- i++;
- j++;
- if (j==m)
- {
- printf("%d\n",i-m+);
- j=F[j-]+;
- }
- }
- else
- {
- if (j==)
- i++;
- else
- j=F[j-]+;
- }
- }
代码:
- #include<bits/stdc++.h>
- using namespace std;
- #define ll long long
- #define pb push_back
- #define mem(a,b) memset((a),(b),sizeof(a))
- const int N=1e3+;
- int f[N]={-};
- char a[N*N];
- char b[N];
- int main()
- {
- /*ios::sync_with_stdio(false);
- cin.tie(0);*/
- scanf("%s",a);
- scanf("%s",b);
- int m=strlen(b);
- int n=strlen(a);
- for(int i=;i<m;i++)
- {
- int j=f[i-];
- while(b[j+]!=b[i]&&j>=)j=f[j];
- if(b[j+]==b[i])f[i]=j+;
- else f[i]=-;
- }
- int i=,j=;
- while(i<n)
- {
- if(a[i]==b[j])
- {
- i++;
- j++;
- if(j==m)
- {
- printf("%d\n",i-m+);
- j=f[j-]+;
- }
- }
- else
- {
- if(j==)i++;
- else j=f[j-]+;
- }
- }
- for(int i=;i<m;i++)
- {
- printf("%d",f[i]+);
- if(i!=m-)printf(" ");
- else printf("\n");
- }
- return ;
- }
代码:
- #include<bits/stdc++.h>
- using namespace std;
- #define ll long long
- #define pb push_back
- #define mem(a,b) memset((a),(b),sizeof(a))
- const int N=1e6+;
- const int M=1e4+;
- int f[M]={-};
- int a[N];
- int b[M];
- int main()
- {
- /*ios::sync_with_stdio(false);
- cin.tie(0);*/
- int t;
- scanf("%d",&t);
- while(t--)
- {
- int n,m;
- scanf("%d%d",&n,&m);
- for(int i=;i<n;i++)scanf("%d",&a[i]);
- for(int i=;i<m;i++)scanf("%d",&b[i]);
- for(int i=;i<m;i++)
- {
- int j=f[i-];
- while(b[j+]!=b[i]&&j>=)j=f[j];
- if(b[j+]==b[i])f[i]=j+;
- else f[i]=-;
- }
- int i=,j=;
- bool flag=true;
- while(i<n)
- {
- if(a[i]==b[j])
- {
- i++;
- j++;
- if(j==m)
- {
- printf("%d\n",i-m+);
- flag=false;
- break;
- }
- }
- else
- {
- if(j==)i++;
- else j=f[j-]+;
- }
- }
- if(flag)printf("-1\n");
- }
- return ;
- }
用next数组求解最小循环节。
代码:
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- using namespace std;
- #define ll long long
- #define pb push_back
- #define mem(a,b) memset((a),(b),sizeof(a))
- const int N=1e6+;
- int f[N]={-};
- char s[N];
- int main()
- {
- /*ios::sync_with_stdio(false);
- cin.tie(0);*/
- while(scanf("%s",s)!=EOF)
- {
- if(s[]=='.')break;
- int m=strlen(s);
- for(int i=;i<m;i++)
- {
- int j=f[i-];
- while(s[j+]!=s[i]&&j>=)j=f[j];
- if(s[j+]==s[i])f[i]=j+;
- else f[i]=-;
- }
- int t=m-(f[m-]+);
- if(m%t)t=m;//如果不整出,那么不存在最小循环节,或者说最小循环节就是字符串本身
- printf("%d\n",m/t);
- }
- return ;
- }
例题4:POJ 1961 Period
求每一段的最小循环节。
代码:
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- using namespace std;
- #define ll long long
- #define pb push_back
- #define mem(a,b) memset((a),(b),sizeof(a))
- const int N=1e6+;
- int f[N]={-};
- char s[N];
- int main()
- {
- /*ios::sync_with_stdio(false);
- cin.tie(0);*/
- int n;
- int c=;
- while(scanf("%d",&n)!=EOF&&n)
- {
- scanf("%s",s);
- c++;
- printf("Test case #%d\n",c);
- int m=strlen(s);
- for(int i=;i<m;i++)
- {
- int j=f[i-];
- while(s[j+]!=s[i]&&j>=)j=f[j];
- if(s[j+]==s[i])f[i]=j+;
- else f[i]=-;
- int t=i-f[i];
- if((i+)%t==&&(i+)/t>)printf("%d %d\n",i+,(i+)/t);
- }
- printf("\n");
- }
- return ;
- }
对差值进行匹配
- #include<bits/stdc++.h>
- using namespace std;
- #define ll long long
- #define pb push_back
- #define mem(a,b) memset(a,b,sizeof(a))
- const int N=2e5+;
- int F[N]={-},A[N],B[N];
- int main(){
- ios::sync_with_stdio(false);
- cin.tie();
- int n,m;
- cin>>n>>m;
- for(int i=;i<n;i++)cin>>A[i];
- for(int i=n-;i>=;i--)A[i]=A[i]-A[i-];
- A[]=;
- for(int i=;i<m;i++)cin>>B[i];
- for(int i=m-;i>=;i--)B[i]=B[i]-B[i-];
- if(m==){
- cout<<n<<endl;
- return ;
- }
- for(int i=;i<m;i++)B[i-]=B[i];
- m--;
- for(int i=;i<m;i++)
- {
- int j=F[i-];
- while(B[j+]!=B[i]&&j>=)j=F[j];
- if(B[j+]==B[i])F[i]=j+;
- else F[i]=-;
- }
- int cnt=;
- /*for(int i=0;i<n;i++)cout<<A[i]<<' ';
- cout<<endl;
- for(int i=0;i<m;i++)cout<<B[i]<<' ';
- cout<<endl;
- for(int i=0;i<m;i++)cout<<F[i]<<' ';
- cout<<endl;*/
- int i=,j=;
- while (i<n)
- {
- if (A[i]==B[j])
- {
- i++;
- j++;
- if (j==m)
- {
- cnt++;
- j=F[j-]+;
- }
- }
- else
- {
- if (j==)
- i++;
- else
- j=F[j-]+;
- }
- //cout<<i<<' '<<j<<endl;
- }
- cout<<cnt<<endl;
- return ;
- }
2.exkmp算法
https://blog.csdn.net/dyx404514/article/details/41831947
模板:
- const int N = 1e6 + ;
- int nxt[N], ex[N];
- void GETNEXT(char *str) {
- int i = , j, po, len=strlen(str);
- nxt[] = len;
- while(str[i] == str[i+] && i+ < len) i++;
- nxt[] = i;
- po = ;
- for(i = ; i < len; i++) {
- if(nxt[i-po] + i < nxt[po] + po)
- nxt[i] = nxt[i-po];
- else {
- j=nxt[po] + po - i;
- if(j < ) j = ;
- while(i + j < len && str[j] == str[j+i])
- j++;
- nxt[i] = j;
- po = i;
- }
- }
- }
- void EXKMP(char *s1,char *s2)
- {
- int i = , j, po, len = strlen(s1), l2=strlen(s2);
- GETNEXT(s2);
- while(s1[i] == s2[i] && i < l2 && i < len) i++;
- ex[] = i;
- po = ;
- for(i = ; i < len; i++)
- {
- if(nxt[i-po] + i < ex[po] + po) ex[i]=nxt[i-po];
- else {
- j = ex[po] + po - i;
- if(j < ) j = ;
- while(i + j < len && j < l2 && s1[j+i] == s2[j]) j++;
- ex[i] = j;
- po = i;
- }
- }
- }
HDU 2594 Simpsons’ Hidden Talents
代码:
- #pragma GCC optimize(2)
- #pragma GCC optimize(3)
- #pragma GCC optimize(4)
- #include<bits/stdc++.h>
- using namespace std;
- #define y1 y11
- #define fi first
- #define se second
- #define pi acos(-1.0)
- #define LL long long
- //#define mp make_pair
- #define pb push_back
- #define ls rt<<1, l, m
- #define rs rt<<1|1, m+1, r
- #define ULL unsigned LL
- #define pll pair<LL, LL>
- #define pli pair<LL, int>
- #define pii pair<int, int>
- #define piii pair<pii, int>
- #define pdd pair<double, double>
- #define mem(a, b) memset(a, b, sizeof(a))
- #define debug(x) cerr << #x << " = " << x << "\n";
- #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
- //head
- const int N = ;
- int nxt[N], ex[N];
- char s[N], t[N];
- void GETNEXT(char *str) {
- int i = , j, po, len = strlen(str);
- nxt[] = len;
- while(str[i] == str[i+] && i+ < len) i++;
- nxt[] = i;
- po = ;
- for(i = ; i < len; i++) {
- if(nxt[i-po] + i < nxt[po] + po)
- nxt[i] = nxt[i-po];
- else {
- j=nxt[po] + po - i;
- if(j < ) j = ;
- while(i + j < len && str[j] == str[j+i])
- j++;
- nxt[i] = j;
- po = i;
- }
- }
- }
- void EXKMP(char *s1,char *s2)
- {
- int i = , j, po, len = strlen(s1), l2 = strlen(s2);
- GETNEXT(s2);
- while(s1[i] == s2[i] && i < l2 && i < len) i++;
- ex[] = i;
- po = ;
- for(i = ; i < len; i++)
- {
- if(nxt[i-po] + i < ex[po] + po) ex[i]=nxt[i-po];
- else {
- j = ex[po] + po - i;
- if(j < ) j = ;
- while(i + j < len && j < l2 && s1[j+i] == s2[j]) j++;
- ex[i] = j;
- po = i;
- }
- }
- }
- int main() {
- while(~scanf("%s", &s)) {
- scanf("%s", &t);
- EXKMP(t, s);
- int len = strlen(t), res = ;
- for (int i = ; i < len; ++i) {
- if(ex[i]+i == len) {
- res = ex[i];
- break;
- }
- }
- for (int i = ; i < res; ++i) putchar(s[i]);
- if(res)putchar(' ');
- printf("%d\n", res);
- }
- return ;
- }
- void FFT_match(char *s1,char *s2,int m,int n)
- {
- reverse(ss1,ss1+m);
- for(int i=;i<m;i++) A[i]=(s1[i]!='*')?(s1[i]-'a'+):;
- for(int i=;i<n;i++) B[i]=(s2[i]!='*')?(s2[i]-'a'+):;
- for(int i=;i<len;i++) a[i]=Comp(A[i]*A[i]*A[i],),b[i]=Comp(B[i],);
- FFT(a,len,);FFT(b,len,);
- for(int i=;i<len;i++) P[i]=P[i]+a[i]*b[i];
- for(int i=;i<len;i++) a[i]=Comp(A[i],),b[i]=Comp(B[i]*B[i]*B[i],);
- FFT(a,len,);FFT(b,len,);
- for(int i=;i<len;i++) P[i]=P[i]+a[i]*b[i];
- for(int i=;i<len;i++) a[i]=Comp(A[i]*A[i],),b[i]=Comp(B[i]*B[i],);
- FFT(a,len,);FFT(b,len,);
- for(int i=;i<len;i++) P[i]=P[i]-a[i]*b[i]*Comp(,);
- FFT(P,len,-);
- for(int i=m-;i<n;i++) if(fabs(P[i].r)<=1e-) printf("%d ",i-m+);
- }
算法笔记--KMP算法 && EXKMP算法的更多相关文章
- <算法笔记>关于快速排序的算法优化排序(顺便给百度百科纠个错)
快速排序是排序算法之中的基本中的基本,虽然越来越多的接口函数将快速排序“完美的封装了起来”,比如C++中的qsort或者<algorithm>中的sort(与stable_sort相对应) ...
- 算法笔记之KMP算法
本文是<算法笔记>KMP算法章节的阅读笔记,文中主要内容来源于<算法笔记>.本文主要介绍了next数组.KMP算法及其应用以及对KMP算法的优化. KMP算法主要用于解决字符串 ...
- 算法:KMP算法
算法:KMP排序 算法分析 KMP算法是一种快速的模式匹配算法.KMP是三位大师:D.E.Knuth.J.H.Morris和V.R.Pratt同时发现的,所以取首字母组成KMP. 少部分图片来自孤~影 ...
- BF算法与KMP算法
BF(Brute Force)算法是普通的模式匹配算法,BF算法的思想就是将目标串S的第一个字符与模式串T的第一个字符进行匹配,若相等,则继续比较S的第二个字符和 T的第二个字符:若不相等,则比较S的 ...
- 机器学习实战 - 读书笔记(12) - 使用FP-growth算法来高效发现频繁项集
前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习心得,这次是第12章 - 使用FP-growth算法来高效发现频繁项集. 基本概念 FP-growt ...
- 机器学习实战 - 读书笔记(11) - 使用Apriori算法进行关联分析
前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习心得,这次是第11章 - 使用Apriori算法进行关联分析. 基本概念 关联分析(associat ...
- 决策树笔记:使用ID3算法
决策树笔记:使用ID3算法 决策树笔记:使用ID3算法 机器学习 先说一个偶然的想法:同样的一堆节点构成的二叉树,平衡树和非平衡树的区别,可以认为是"是否按照重要度逐渐降低"的顺序 ...
- 学习Java 以及对几大基本排序算法(对算法笔记书的研究)的一些学习总结(Java对算法的实现持续更新中)
Java排序一,冒泡排序! 刚刚开始学习Java,但是比较有兴趣研究算法.最近看了一本算法笔记,刚开始只是打算随便看看,但是发现这本书非常不错,尤其是对排序算法,以及哈希函数的一些解释,让我非常的感兴 ...
- 第四十一课 KMP子串查找算法
问题: 右移的位数和目标串没有多大的关系,和子串有关系. 已匹配的字符数现在已经有了,部分匹配值还没有. 前六位匹配成功就去查找PMT中的第六位. 现在的任务就是求得部分匹配表. 问题:怎么得到部分匹 ...
随机推荐
- php开启mbstring扩展并设置支持utf-8编码
前一段时间使用一个服务的接口,因为调用接口时使用的参数里面有中文,调用接口会出现异常问题,后来才明白是编码不一致的问题.然而,我本地项目开发使用的是utf-8,接口那边也是需要utf-8的,那么问题来 ...
- rpm服务的独立服务管理
/etc/init.d 启动脚本的位置 /etc/sysconfig/ 初始化环境配置文件 /etc/ 配置文件位置 /etc/xinetd.conf xinetd配置文件 /etc/xine ...
- MySQL创建数据表并建立主外键关系
为mysql数据表建立主外键需要注意以下几点: 需要建立主外键关系的两个表的存储引擎必须是InnoDB. 外键列和参照列必须具有相似的数据类型,即可以隐式转换的数据类型. 外键列和参照列必须创建索引, ...
- python getatime() 查看文件的访问时间
import time,os def main(): file_name=r'C:\Temp\Req.xml' file_times_access=time.localtime(os.path.get ...
- OVS中的key解析
OVS在处理每条流的时候,先根据每条流生产相应的key,然后根据key匹配相应的流表,根据流表中的action操作来处理每条流,本文对key的结构体进行分析,看看对于一条流会提出那些特征信息.对于ke ...
- linux常用命令(替换)
1. vi 模式下的替换命令: s 表示替换(substitute),g表示全局搜索(global search) :s/vivian/sky/ 替换当前行第一个 vivian 为 sky :s/vi ...
- Linux服务器---mysql忘记root密码
忘记root密码 如果不小心忘记了root密码,那么mysql就不能再登录了,这时就要重置root密码才行.通过下面的步骤,我们可以重新设置root密码. 1.退出mysql [root@localh ...
- 第一次使用crontab linux选择编辑器问题
第一次使用crontab linux选择编辑器问题 第一次使用crontab 时,会出现no crontab for root - using an empty one“Select a editor ...
- pyDay7
内容来自廖雪峰的官方网站 1.如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration). 2.只要是可迭代对象,无论有无下标, ...
- 安装webpack出现警告: fsevents@^1.0.0 (node_modules\chokidar\node_modules\fsevents):
警告如下: npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.0 (node_modules\chokidar\node_mo ...