KMP:在主串S中找子串T的位置KMP算法的时间复杂度O(|S|+|T|)。

  1. #define maxn 1000
  2. char s[maxn],t[maxn];//s为主串,t为子串
  3. int net[maxn],l1,l2;//l1为主串长度,l2为子串长度
  4. void get_next() {
  5. int i=,j=-;
  6. net[]=-;
  7. while(i<l2) {
  8. if (j==- ||t[i]==t[j])
  9. {
  10. ++i,++j;
  11. if (t[i]!=t[j]) net[i]=j; //优化next数组
  12. else net[i]=net[j];
  13. }
  14. else j=net[j];
  15. }
  16. /*for (i=0;i<l2;i++)
  17. printf("next[%d]=%d\n",i,next[i]); */
  18. }
  19. //返回子串在主串第pos个字符之后的位置
  20. //若不存在则返回0
  21. int KMP(int pos)
  22. {
  23. int i=pos,j=;
  24. get_next(); //核心部分
  25. while(i<l1&&j<l2) {
  26. if (j==-||s[i]==t[j]) i++,j++;
  27. else j=net[j];
  28. }
  29. if (j==l2) return i-l2;
  30. else return ;
  31. }

1

  1. void getNext() {
  2. Next[] = ;
  3. for (int i = , j = ; i <= n; i++) {
  4. while(j > && a[i] != a[j+]) j = Next[j];
  5. if (a[i] == a[j+]) j++;
  6. Next[i] = j;
  7. }
  8. }
  9. void KMP() {
  10. for (int i = , j = ; i <= m; i++) {
  11. while(j > && (j == n || b[i] != a[j+]))
  12. j = Next[j];
  13. if (b[i] == a[j+]) j++;
  14. f[i] = j;
  15. // if (f[i] == n) 此时是A在B中的某一次出现
  16. }
  17. }

2(来着算法竞赛进阶指南)

扩展KMP:

给定串S,和串T,设S的长度为n,T的长度为m,求T与S的每一个后缀(包括S)的最长公共前缀。复杂度为O(n+m)。

设extend数组,extend[i]表示T与S[i,n-1]的最长公共前缀,要求出所有extend[i](0<=i<n)。

注意到,如果有一个位置extend[i]=m,则表示T在S中出现,而且是在位置i出现,这就是标准的KMP问题,所以说拓展kmp是对KMP算法的扩展,所以一般将它称为扩展KMP算法。

详细过程参考博客: https://blog.csdn.net/qq_40160605/article/details/80407554

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

  1. const int K=;
  2. int nt[K],extand[K];
  3. char S[K];
  4. void Getnext(char *T,int *next)
  5. {
  6. int len=strlen(T),a=;
  7. next[]=len;
  8. while(a<len- && T[a]==T[a+]) a++;
  9. next[]=a;
  10. a=;
  11. for(int k=; k<len; k++)
  12. {
  13. int p=a+next[a]-,L=next[k-a];
  14. if( (k-)+L >= p)
  15. {
  16. int j = (p-k+)> ? (p-k+) : ;
  17. while(k+j<len && T[k+j]==T[j]) j++;
  18. next[k]=j;
  19. a=k;
  20. }
  21. else next[k]=L;
  22. }
  23. }
  24. void GetExtand(char *S,char *T,int *next)
  25. {
  26. Getnext(T,next);
  27. int slen=strlen(S),tlen=strlen(T),a=;
  28. int MinLen = slen < tlen ? slen : tlen;
  29. while(a<MinLen && S[a]==T[a]) a++;
  30. extand[]=a;
  31. a=;
  32. for(int k=; k<slen; k++)
  33. {
  34. int p=a+extand[a]-, L=next[k-a];
  35. if( (k-)+L >= p)
  36. {
  37. int j= (p-k+) > ? (p-k+) : ;
  38. while(k+j<slen && j<tlen && S[k+j]==T[j]) j++;
  39. extand[k]=j;
  40. a=k;
  41. }
  42. else extand[k]=L;
  43. }
  44. }
  45. int main()
  46. {
  47. while(scanf("%s%s",S,T)==)
  48. {
  49. GetExtand(S,T,nt);
  50. for(int i=; i<strlen(T); i++)
  51. printf("%d ",nt[i]);
  52. puts("");
  53. for(int i=; i<strlen(S); i++)
  54. printf("%d ",extand[i]);
  55. puts("");
  56. }
  57. return ;
  58. }

扩展KMP

KMP 和 扩展KMP的更多相关文章

  1. KMP和扩展KMP【转】

    这种东西基本上在纸上自己推导一下就能做出来XD 转发注明出处 KMP 给出两个字符串A(称为模板串)和B(称为子串),长度分别为lenA和lenB,要求在线性时间内,对于每个A[i] (0<=i ...

  2. KMP与扩展KMP

    原文转自:http://www.cppblog.com/MatoNo1/archive/2011/04/17/144390.aspx KMP:给出两个字符串A(称为模板串)和B(称为子串),长度分别为 ...

  3. Manacher模板,kmp,扩展kmp,最小表示法模板

    *N]; //储存临时串 *N];//中间记录 int Manacher(char tmp[]) { int len=strlen(tmp); ; ;i<len;i++) { s[cnt++]= ...

  4. KMP && Manacher && 扩展KMP整理

    KMP算法: kmp示例代码: void cal_next(char *str, int *next, int len) { next[0] = -1;//next[0]初始化为-1,-1表示不存在相 ...

  5. KMP和扩展KMP

    文章网上太多这里提一下代码细节: KMP: scanf("%s\n",s); scanf("%s\n",t); int ls=strlen(s),lt=strl ...

  6. kmp模板 && 扩展kmp模板

    kmp模板: #include <bits/stdc++.h> #define PB push_back #define MP make_pair using namespace std; ...

  7. 【kmp或扩展kmp】HDU 6153 A Secret

    acm.hdu.edu.cn/showproblem.php?pid=6153 [题意] 给定字符串A和B,求B的所有后缀在A中出现次数与其长度的乘积之和 A和B的长度最大为1e6 方法一:扩展kmp ...

  8. KMP 、扩展KMP、Manacher算法 总结

    一. KMP 1 找字符串x是否存在于y串中,或者存在了几次 HDU1711 Number Sequence HDU1686 Oulipo HDU2087 剪花布条 2.求多个字符串的最长公共子串 P ...

  9. 666 专题三 KMP &#38; 扩展KMP &#38; Manacher

    KMP: Problem A.Number Sequence d.求子串首次出现在主串中的位置 s. c. #include<iostream> #include<stdio.h&g ...

  10. kmp与扩展kmp模板

    kmp 1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include & ...

随机推荐

  1. H3C ICMP

  2. [学习笔记]整体DP

    问题: 有一些问题,通常见于二维的DP,另一维记录当前x的信息,但是这一维过大无法开下,O(nm)也无法通过. 但是如果发现,对于x,在第二维的一些区间内,取值都是相同的,并且这样的区间是有限个,就可 ...

  3. H3C 配置二层ACL

  4. git把某个文件去除版本控制

    谢谢@jessicway 同学的提醒.我之前没考虑只需要删除服务器上已提交的文件,但是本地不想删除的情况. 我们先看看 git rm 命令的说明 可以看到其实加上 --cached 参数就可以实现只去 ...

  5. 备战省赛组队训练赛第十八场(UPC)

    传送门 题解:by 青岛大学 A:https://blog.csdn.net/birdmanqin/article/details/89789424 B:https://blog.csdn.net/b ...

  6. H3C 端口绑定典型配置举例

  7. 被孟加拉题吊打的ACM考试

    https://codeforces.com/gym/101864 题目并不难 B 考虑新加入的线段和之前线段有交的个数 总数-不交的,不交的:右端点在[l,r]左边,左端点在[l,r]右边的. 维护 ...

  8. 【u034】追查坏奶牛

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 你第一天接手三鹿牛奶公司就发生了一件倒霉的事情:公司不小心发送了一批有三聚氰胺的牛奶.很不幸,你发现这 ...

  9. 【转】Elasticsearch学习笔记

    一.常用术语 索引(Index).类型(Type).文档(Document) 索引Index是含有相同属性的文档集合.索引在ES中是通过一个名字来识别的,且必须是英文字母小写,且不含中划线(-):可类 ...

  10. 【Docker】Jenkins的安装与更新

    一.Jenkins安装 1.获取docker镜像 2.查看jenkins版本 3.启动jenkins容器 docker run -d --name jenkins_01 -p 8081:8080 -v ...