1.KMP算法

这个博客写的不错:http://www.cnblogs.com/SYCstudio/p/7194315.html

模板:

next数组的求解,那个循环本质就是如果相同前后缀不能加上该位置成就该位置的next数组就一直找相同前后缀的相同前后缀。

求解前缀数组F(也叫next数组):

  1. for (int i=;i<m;i++)
  2. {
  3. int j=F[i-];
  4. while ((B[j+]!=B[i])&&(j>=))
  5. j=F[j];
  6. if (B[j+]==B[i])
  7. F[i]=j+;
  8. else
  9. F[i]=-;
  10. }

利用F数组寻找匹配,这里我们是每找到一个匹配就输出其开始的位置:

  1. while (i<n)
  2. {
  3. if (A[i]==B[j])
  4. {
  5. i++;
  6. j++;
  7. if (j==m)
  8. {
  9. printf("%d\n",i-m+);
  10. j=F[j-]+;
  11. }
  12. }
  13. else
  14. {
  15. if (j==)
  16. i++;
  17. else
  18. j=F[j-]+;
  19. }
  20. }

例题1:P3375 【模板】KMP字符串匹配

代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define ll long long
  4. #define pb push_back
  5. #define mem(a,b) memset((a),(b),sizeof(a))
  6. const int N=1e3+;
  7. int f[N]={-};
  8. char a[N*N];
  9. char b[N];
  10.  
  11. int main()
  12. {
  13. /*ios::sync_with_stdio(false);
  14. cin.tie(0);*/
  15. scanf("%s",a);
  16. scanf("%s",b);
  17. int m=strlen(b);
  18. int n=strlen(a);
  19. for(int i=;i<m;i++)
  20. {
  21. int j=f[i-];
  22. while(b[j+]!=b[i]&&j>=)j=f[j];
  23. if(b[j+]==b[i])f[i]=j+;
  24. else f[i]=-;
  25. }
  26.  
  27. int i=,j=;
  28. while(i<n)
  29. {
  30. if(a[i]==b[j])
  31. {
  32. i++;
  33. j++;
  34. if(j==m)
  35. {
  36. printf("%d\n",i-m+);
  37. j=f[j-]+;
  38. }
  39. }
  40. else
  41. {
  42. if(j==)i++;
  43. else j=f[j-]+;
  44. }
  45. }
  46.  
  47. for(int i=;i<m;i++)
  48. {
  49. printf("%d",f[i]+);
  50. if(i!=m-)printf(" ");
  51. else printf("\n");
  52. }
  53. return ;
  54. }

例题2:HDU 1711 Number Sequence

代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define ll long long
  4. #define pb push_back
  5. #define mem(a,b) memset((a),(b),sizeof(a))
  6. const int N=1e6+;
  7. const int M=1e4+;
  8. int f[M]={-};
  9. int a[N];
  10. int b[M];
  11.  
  12. int main()
  13. {
  14. /*ios::sync_with_stdio(false);
  15. cin.tie(0);*/
  16. int t;
  17. scanf("%d",&t);
  18. while(t--)
  19. {
  20. int n,m;
  21. scanf("%d%d",&n,&m);
  22. for(int i=;i<n;i++)scanf("%d",&a[i]);
  23. for(int i=;i<m;i++)scanf("%d",&b[i]);
  24.  
  25. for(int i=;i<m;i++)
  26. {
  27. int j=f[i-];
  28. while(b[j+]!=b[i]&&j>=)j=f[j];
  29. if(b[j+]==b[i])f[i]=j+;
  30. else f[i]=-;
  31. }
  32.  
  33. int i=,j=;
  34. bool flag=true;
  35. while(i<n)
  36. {
  37. if(a[i]==b[j])
  38. {
  39. i++;
  40. j++;
  41. if(j==m)
  42. {
  43. printf("%d\n",i-m+);
  44. flag=false;
  45. break;
  46. }
  47. }
  48. else
  49. {
  50. if(j==)i++;
  51. else j=f[j-]+;
  52. }
  53. }
  54. if(flag)printf("-1\n");
  55. }
  56.  
  57. return ;
  58. }

例题3:POJ 2406 Power Strings

用next数组求解最小循环节。

代码:

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. using namespace std;
  5. #define ll long long
  6. #define pb push_back
  7. #define mem(a,b) memset((a),(b),sizeof(a))
  8. const int N=1e6+;
  9. int f[N]={-};
  10. char s[N];
  11.  
  12. int main()
  13. {
  14. /*ios::sync_with_stdio(false);
  15. cin.tie(0);*/
  16. while(scanf("%s",s)!=EOF)
  17. {
  18. if(s[]=='.')break;
  19. int m=strlen(s);
  20. for(int i=;i<m;i++)
  21. {
  22. int j=f[i-];
  23. while(s[j+]!=s[i]&&j>=)j=f[j];
  24. if(s[j+]==s[i])f[i]=j+;
  25. else f[i]=-;
  26. }
  27.  
  28. int t=m-(f[m-]+);
  29. if(m%t)t=m;//如果不整出,那么不存在最小循环节,或者说最小循环节就是字符串本身
  30. printf("%d\n",m/t);
  31. }
  32. return ;
  33. }

例题4:POJ 1961 Period

求每一段的最小循环节。

代码:

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. using namespace std;
  5. #define ll long long
  6. #define pb push_back
  7. #define mem(a,b) memset((a),(b),sizeof(a))
  8. const int N=1e6+;
  9. int f[N]={-};
  10. char s[N];
  11.  
  12. int main()
  13. {
  14. /*ios::sync_with_stdio(false);
  15. cin.tie(0);*/
  16. int n;
  17. int c=;
  18. while(scanf("%d",&n)!=EOF&&n)
  19. {
  20. scanf("%s",s);
  21. c++;
  22. printf("Test case #%d\n",c);
  23. int m=strlen(s);
  24. for(int i=;i<m;i++)
  25. {
  26. int j=f[i-];
  27. while(s[j+]!=s[i]&&j>=)j=f[j];
  28. if(s[j+]==s[i])f[i]=j+;
  29. else f[i]=-;
  30. int t=i-f[i];
  31. if((i+)%t==&&(i+)/t>)printf("%d %d\n",i+,(i+)/t);
  32. }
  33. printf("\n");
  34. }
  35. return ;
  36. }

 例题5:471D - MUH and Cube Walls

对差值进行匹配

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define ll long long
  4. #define pb push_back
  5. #define mem(a,b) memset(a,b,sizeof(a))
  6.  
  7. const int N=2e5+;
  8. int F[N]={-},A[N],B[N];
  9. int main(){
  10. ios::sync_with_stdio(false);
  11. cin.tie();
  12. int n,m;
  13. cin>>n>>m;
  14. for(int i=;i<n;i++)cin>>A[i];
  15. for(int i=n-;i>=;i--)A[i]=A[i]-A[i-];
  16. A[]=;
  17. for(int i=;i<m;i++)cin>>B[i];
  18. for(int i=m-;i>=;i--)B[i]=B[i]-B[i-];
  19. if(m==){
  20. cout<<n<<endl;
  21. return ;
  22. }
  23. for(int i=;i<m;i++)B[i-]=B[i];
  24. m--;
  25. for(int i=;i<m;i++)
  26. {
  27. int j=F[i-];
  28. while(B[j+]!=B[i]&&j>=)j=F[j];
  29. if(B[j+]==B[i])F[i]=j+;
  30. else F[i]=-;
  31. }
  32. int cnt=;
  33. /*for(int i=0;i<n;i++)cout<<A[i]<<' ';
  34. cout<<endl;
  35. for(int i=0;i<m;i++)cout<<B[i]<<' ';
  36. cout<<endl;
  37. for(int i=0;i<m;i++)cout<<F[i]<<' ';
  38. cout<<endl;*/
  39. int i=,j=;
  40. while (i<n)
  41. {
  42. if (A[i]==B[j])
  43. {
  44. i++;
  45. j++;
  46. if (j==m)
  47. {
  48. cnt++;
  49. j=F[j-]+;
  50. }
  51. }
  52. else
  53. {
  54. if (j==)
  55. i++;
  56. else
  57. j=F[j-]+;
  58. }
  59. //cout<<i<<' '<<j<<endl;
  60. }
  61. cout<<cnt<<endl;
  62. return ;
  63. }

 2.exkmp算法

https://blog.csdn.net/dyx404514/article/details/41831947

模板:

  1. const int N = 1e6 + ;
  2. int nxt[N], ex[N];
  3. void GETNEXT(char *str) {
  4. int i = , j, po, len=strlen(str);
  5. nxt[] = len;
  6. while(str[i] == str[i+] && i+ < len) i++;
  7. nxt[] = i;
  8. po = ;
  9. for(i = ; i < len; i++) {
  10. if(nxt[i-po] + i < nxt[po] + po)
  11. nxt[i] = nxt[i-po];
  12. else {
  13. j=nxt[po] + po - i;
  14. if(j < ) j = ;
  15. while(i + j < len && str[j] == str[j+i])
  16. j++;
  17. nxt[i] = j;
  18. po = i;
  19. }
  20. }
  21. }
  22. void EXKMP(char *s1,char *s2)
  23. {
  24. int i = , j, po, len = strlen(s1), l2=strlen(s2);
  25. GETNEXT(s2);
  26. while(s1[i] == s2[i] && i < l2 && i < len) i++;
  27. ex[] = i;
  28. po = ;
  29. for(i = ; i < len; i++)
  30. {
  31. if(nxt[i-po] + i < ex[po] + po) ex[i]=nxt[i-po];
  32. else {
  33. j = ex[po] + po - i;
  34. if(j < ) j = ;
  35. while(i + j < len && j < l2 && s1[j+i] == s2[j]) j++;
  36. ex[i] = j;
  37. po = i;
  38. }
  39. }
  40. }

HDU 2594 Simpsons’ Hidden Talents

代码:

  1. #pragma GCC optimize(2)
  2. #pragma GCC optimize(3)
  3. #pragma GCC optimize(4)
  4. #include<bits/stdc++.h>
  5. using namespace std;
  6. #define y1 y11
  7. #define fi first
  8. #define se second
  9. #define pi acos(-1.0)
  10. #define LL long long
  11. //#define mp make_pair
  12. #define pb push_back
  13. #define ls rt<<1, l, m
  14. #define rs rt<<1|1, m+1, r
  15. #define ULL unsigned LL
  16. #define pll pair<LL, LL>
  17. #define pli pair<LL, int>
  18. #define pii pair<int, int>
  19. #define piii pair<pii, int>
  20. #define pdd pair<double, double>
  21. #define mem(a, b) memset(a, b, sizeof(a))
  22. #define debug(x) cerr << #x << " = " << x << "\n";
  23. #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
  24. //head
  25.  
  26. const int N = ;
  27. int nxt[N], ex[N];
  28. char s[N], t[N];
  29. void GETNEXT(char *str) {
  30. int i = , j, po, len = strlen(str);
  31. nxt[] = len;
  32. while(str[i] == str[i+] && i+ < len) i++;
  33. nxt[] = i;
  34. po = ;
  35. for(i = ; i < len; i++) {
  36. if(nxt[i-po] + i < nxt[po] + po)
  37. nxt[i] = nxt[i-po];
  38. else {
  39. j=nxt[po] + po - i;
  40. if(j < ) j = ;
  41. while(i + j < len && str[j] == str[j+i])
  42. j++;
  43. nxt[i] = j;
  44. po = i;
  45. }
  46. }
  47. }
  48. void EXKMP(char *s1,char *s2)
  49. {
  50. int i = , j, po, len = strlen(s1), l2 = strlen(s2);
  51. GETNEXT(s2);
  52. while(s1[i] == s2[i] && i < l2 && i < len) i++;
  53. ex[] = i;
  54. po = ;
  55. for(i = ; i < len; i++)
  56. {
  57. if(nxt[i-po] + i < ex[po] + po) ex[i]=nxt[i-po];
  58. else {
  59. j = ex[po] + po - i;
  60. if(j < ) j = ;
  61. while(i + j < len && j < l2 && s1[j+i] == s2[j]) j++;
  62. ex[i] = j;
  63. po = i;
  64. }
  65. }
  66. }
  67. int main() {
  68. while(~scanf("%s", &s)) {
  69. scanf("%s", &t);
  70. EXKMP(t, s);
  71. int len = strlen(t), res = ;
  72. for (int i = ; i < len; ++i) {
  73. if(ex[i]+i == len) {
  74. res = ex[i];
  75. break;
  76. }
  77. }
  78. for (int i = ; i < res; ++i) putchar(s[i]);
  79. if(res)putchar(' ');
  80. printf("%d\n", res);
  81. }
  82. return ;
  83. }

FFT求带通配符的字符串匹配

  1. void FFT_match(char *s1,char *s2,int m,int n)
  2. {
  3. reverse(ss1,ss1+m);
  4. for(int i=;i<m;i++) A[i]=(s1[i]!='*')?(s1[i]-'a'+):;
  5. for(int i=;i<n;i++) B[i]=(s2[i]!='*')?(s2[i]-'a'+):;
  6.  
  7. for(int i=;i<len;i++) a[i]=Comp(A[i]*A[i]*A[i],),b[i]=Comp(B[i],);
  8. FFT(a,len,);FFT(b,len,);
  9. for(int i=;i<len;i++) P[i]=P[i]+a[i]*b[i];
  10.  
  11. for(int i=;i<len;i++) a[i]=Comp(A[i],),b[i]=Comp(B[i]*B[i]*B[i],);
  12. FFT(a,len,);FFT(b,len,);
  13. for(int i=;i<len;i++) P[i]=P[i]+a[i]*b[i];
  14.  
  15. for(int i=;i<len;i++) a[i]=Comp(A[i]*A[i],),b[i]=Comp(B[i]*B[i],);
  16. FFT(a,len,);FFT(b,len,);
  17. for(int i=;i<len;i++) P[i]=P[i]-a[i]*b[i]*Comp(,);
  18.  
  19. FFT(P,len,-);
  20. for(int i=m-;i<n;i++) if(fabs(P[i].r)<=1e-) printf("%d ",i-m+);
  21. }

算法笔记--KMP算法 && EXKMP算法的更多相关文章

  1. <算法笔记>关于快速排序的算法优化排序(顺便给百度百科纠个错)

    快速排序是排序算法之中的基本中的基本,虽然越来越多的接口函数将快速排序“完美的封装了起来”,比如C++中的qsort或者<algorithm>中的sort(与stable_sort相对应) ...

  2. 算法笔记之KMP算法

    本文是<算法笔记>KMP算法章节的阅读笔记,文中主要内容来源于<算法笔记>.本文主要介绍了next数组.KMP算法及其应用以及对KMP算法的优化. KMP算法主要用于解决字符串 ...

  3. 算法:KMP算法

    算法:KMP排序 算法分析 KMP算法是一种快速的模式匹配算法.KMP是三位大师:D.E.Knuth.J.H.Morris和V.R.Pratt同时发现的,所以取首字母组成KMP. 少部分图片来自孤~影 ...

  4. BF算法与KMP算法

    BF(Brute Force)算法是普通的模式匹配算法,BF算法的思想就是将目标串S的第一个字符与模式串T的第一个字符进行匹配,若相等,则继续比较S的第二个字符和 T的第二个字符:若不相等,则比较S的 ...

  5. 机器学习实战 - 读书笔记(12) - 使用FP-growth算法来高效发现频繁项集

    前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习心得,这次是第12章 - 使用FP-growth算法来高效发现频繁项集. 基本概念 FP-growt ...

  6. 机器学习实战 - 读书笔记(11) - 使用Apriori算法进行关联分析

    前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习心得,这次是第11章 - 使用Apriori算法进行关联分析. 基本概念 关联分析(associat ...

  7. 决策树笔记:使用ID3算法

    决策树笔记:使用ID3算法 决策树笔记:使用ID3算法 机器学习 先说一个偶然的想法:同样的一堆节点构成的二叉树,平衡树和非平衡树的区别,可以认为是"是否按照重要度逐渐降低"的顺序 ...

  8. 学习Java 以及对几大基本排序算法(对算法笔记书的研究)的一些学习总结(Java对算法的实现持续更新中)

    Java排序一,冒泡排序! 刚刚开始学习Java,但是比较有兴趣研究算法.最近看了一本算法笔记,刚开始只是打算随便看看,但是发现这本书非常不错,尤其是对排序算法,以及哈希函数的一些解释,让我非常的感兴 ...

  9. 第四十一课 KMP子串查找算法

    问题: 右移的位数和目标串没有多大的关系,和子串有关系. 已匹配的字符数现在已经有了,部分匹配值还没有. 前六位匹配成功就去查找PMT中的第六位. 现在的任务就是求得部分匹配表. 问题:怎么得到部分匹 ...

随机推荐

  1. php开启mbstring扩展并设置支持utf-8编码

    前一段时间使用一个服务的接口,因为调用接口时使用的参数里面有中文,调用接口会出现异常问题,后来才明白是编码不一致的问题.然而,我本地项目开发使用的是utf-8,接口那边也是需要utf-8的,那么问题来 ...

  2. rpm服务的独立服务管理

    /etc/init.d  启动脚本的位置 /etc/sysconfig/ 初始化环境配置文件 /etc/   配置文件位置 /etc/xinetd.conf  xinetd配置文件 /etc/xine ...

  3. MySQL创建数据表并建立主外键关系

    为mysql数据表建立主外键需要注意以下几点: 需要建立主外键关系的两个表的存储引擎必须是InnoDB. 外键列和参照列必须具有相似的数据类型,即可以隐式转换的数据类型. 外键列和参照列必须创建索引, ...

  4. python getatime() 查看文件的访问时间

    import time,os def main(): file_name=r'C:\Temp\Req.xml' file_times_access=time.localtime(os.path.get ...

  5. OVS中的key解析

    OVS在处理每条流的时候,先根据每条流生产相应的key,然后根据key匹配相应的流表,根据流表中的action操作来处理每条流,本文对key的结构体进行分析,看看对于一条流会提出那些特征信息.对于ke ...

  6. linux常用命令(替换)

    1. vi 模式下的替换命令: s 表示替换(substitute),g表示全局搜索(global search) :s/vivian/sky/ 替换当前行第一个 vivian 为 sky :s/vi ...

  7. Linux服务器---mysql忘记root密码

    忘记root密码 如果不小心忘记了root密码,那么mysql就不能再登录了,这时就要重置root密码才行.通过下面的步骤,我们可以重新设置root密码. 1.退出mysql [root@localh ...

  8. 第一次使用crontab linux选择编辑器问题

    第一次使用crontab linux选择编辑器问题 第一次使用crontab 时,会出现no crontab for root - using an empty one“Select a editor ...

  9. pyDay7

    内容来自廖雪峰的官方网站 1.如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration). 2.只要是可迭代对象,无论有无下标, ...

  10. 安装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 ...