首先,明白Ex-KMP是干什么的:

给定两个字符串母串S和子串T(长度分别为n和m),下标从0开始,定义extend[i]等于S[i]…S[n-1]与T的最长公共前缀的长度,求出所有的extend[i]。

简单来说,就是求母串的每个后缀与子串的最长公共前缀长度,存在extend数组中。

即:一个母串,一个子串,多次匹配


例题链接:J - 好吃不过饺子

两个数组,a[n]和b[m],若有一个数k使得 a[k]+b[0]=a[k+1]+b[1]…=a[k+m-1]+b[m-1],求所有满足条件的k。

输入第一行为n和m,第二行为a[n],第三行为b[m]。

要求输出第一行为k的个数,第二行升序输出所有满足要求的k值。

很明显,a[k]=b[0],a[k+1]=b[1] … a[k+m-1]=b[m-1],

拿出来就是,a[k]到a[k+m-1] 等于 b[0]到b[m-1]

代码如下:

  1. #include<cstdio>
  2. #include<cstring>
  3. using namespace std;
  4. const int maxn = 1e5 + 5; //字符串长度最大值
  5. int as[maxn], bs[maxn], a[maxn], b[maxn], ans[maxn];
  6. int n, m;
  7. int Next[maxn], ex[maxn]; //ex数组即为extend数组
  8. void GETNEXT(int *str) //预处理计算next数组
  9. {
  10. int i = 0, j, po, len = m - 1;
  11. Next[0] = len;//初始化Next[0]
  12. while (str[i] == str[i + 1] && i + 1<len)//计算Next[1]
  13. i++;
  14. Next[1] = i;
  15. po = 1;//初始化po的位置
  16. for (i = 2; i<len; i++)
  17. {
  18. if (Next[i - po] + i<Next[po] + po)//第一种情况,可以直接得到Next[i]的值
  19. Next[i] = Next[i - po];
  20. else//第二种情况,要继续匹配才能得到Next[i]的值
  21. {
  22. j = Next[po] + po - i;
  23. if (j<0)j = 0;//如果i>po+Next[po],则要从头开始匹配
  24. while (i + j<len&&str[j] == str[j + i])//计算Next[i]
  25. j++;
  26. Next[i] = j;
  27. po = i;//更新po的位置
  28. }
  29. }
  30. }
  31. //计算extend数组
  32. void EXKMP(int *s1, int *s2)
  33. {
  34. int i = 0, j, po, len = n-1, l2 = m-1;
  35. GETNEXT(s2);//计算子串的next数组
  36. while (s1[i] == s2[i] && i<l2&&i<len)//计算ex[0]
  37. i++;
  38. ex[0] = i;
  39. po = 0;//初始化po的位置
  40. for (i = 1; i<len; i++)
  41. {
  42. if (Next[i - po] + i<ex[po] + po)//第一种情况,直接可以得到ex[i]的值
  43. ex[i] = Next[i - po];
  44. else//第二种情况,要继续匹配才能得到ex[i]的值
  45. {
  46. j = ex[po] + po - i;
  47. if (j<0)j = 0;//如果i>ex[po]+po则要从头开始匹配
  48. while (i + j<len&&j<l2&&s1[j + i] == s2[j])//计算ex[i]
  49. j++;
  50. ex[i] = j;
  51. po = i;//更新po的位置
  52. }
  53. }
  54. }
  55. int main() {
  56. scanf("%d %d", &n, &m);
  57. for (int i = 0; i < n; i++)
  58. scanf("%d", &a[i]);
  59. for (int i = 0; i < n - 1; i++)
  60. as[i] = a[i] - a[i + 1];
  61. for (int i = 0; i < m; i++)
  62. scanf("%d", &b[i]);
  63. for (int i = 0; i < m - 1; i++)
  64. bs[i] = b[i + 1] - b[i];
  65. memset(Next, 0, sizeof(Next));
  66. EXKMP(as, bs);
  67. int cnt = 0;
  68. for (int i = 0; i < n - 1; i++)
  69. if (ex[i] == m - 1) {
  70. ans[cnt++] = i;
  71. }
  72. printf("%d\n", cnt);
  73. for (int i = 0; i < cnt; i++)
  74. printf("%d ", ans[i]);
  75. return 0;
  76. }

Ex-KMP(模板)的更多相关文章

  1. hdu 1686 KMP模板

    // hdu 1686 KMP模板 // 没啥好说的,KMP裸题,这里是MP模板 #include <cstdio> #include <iostream> #include ...

  2. Oulipo HDU 1686 KMP模板

    题目大意:求模式串在主串中的出现次数. 题目思路:KMP模板题 #include<iostream> #include<algorithm> #include<cstri ...

  3. KMP模板(bin)

    KMP模板 主要是kuangbin的模板,之后加了一点我的习惯和理解. kmpN() 作用:构造next数组 参数:模式串,模式串长度 kmpC() 作用:返回模式串在主串中出现的次数(可重复) 参数 ...

  4. HDU 1711 - Number Sequence - [KMP模板题]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1711 Time Limit: 10000/5000 MS (Java/Others) Memory L ...

  5. HDU 1711 Number Sequence(KMP模板)

    http://acm.hdu.edu.cn/showproblem.php?pid=1711 这道题就是一个KMP模板. #include<iostream> #include<cs ...

  6. 剪花布条---hdu2087(kmp模板)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2087 kmp模板题: #include <cstdio> #include <cst ...

  7. Oulipo----poj3461(kmp模板)

    题目链接:http://poj.org/problem?id=3461 和 减花布条 的题对比一下: 求s2中s1的个数kmp模板: #include<stdio.h> #include& ...

  8. kmp模板 && 扩展kmp模板

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

  9. kuangbin专题16B(kmp模板)

    题目链接: https://vjudge.net/contest/70325#problem/B 题意: 输出模式串在主串中出现的次数 思路: kmp模板 在 kmp 函数中匹配成功计数加一, 再令 ...

  10. [HDU1711]KMP模板

    解题关键:1.直接套kmp模板即可,注意最后输出的位置,需要在索引的位置+1. 2.next用作数组名在oj中会编译错误, 3.选用g++,只有g++才会接受bits/stdc++.h OJ中g++和 ...

随机推荐

  1. 一键安装php5.6.40脚本(LAMP环境)

    #!/bin/bash #安装依赖软件 yum -y install libxml2-devel curl-devel libjpeg libjpeg-devel libpng libpng-deve ...

  2. 解决mysql登录报错ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)问题

    问题描述: 在ubuntu14.04上安装完MYSQL后,MYSQL默认给分配了一个默认密码,但当自己在终端上使用默认密码登录的时候,总会提示一个授权失败的错误. 报错信息:Access denied ...

  3. [RHEL8]安装Docker Problem: package docker-ce-3:19.03.6-3.el7.x86_64 requires containerd.io

    系统环境 # cat /etc/redhat-release Red Hat Enterprise Linux release 8.0 (Ootpa) 安装依赖 # yum install -y yu ...

  4. 杭电-------2048不容易系列之(4)考新郎(C语言)

    /* 思路:有n位新郎,但是又m位新郎会找错,那么有n-m位新郎会找对,而找对的n-m位新郎的找发就是在 n位新郎中随机找n-m位有多少种排列组合公式有n!/(m!*(n-m!)),而另外找错的新郎则 ...

  5. Apache 的多站点配置

    1.修改httpd.conf 文件 Apache的主配置文件路径: D:\phpTools\Apache24\conf 用编辑器打开 httpd.conf 文件,查找 #Include conf/ex ...

  6. Nginx 核心配置

    nginx的核心配置在conf/nginx.conf中. 全局配置块 user root; #运行worker进程的账户,user   用户   [组],默认以nobody账户运行 worker_pr ...

  7. HUE下载HDFS文件时报ERR_CONNECTION_TIMED_OUT错误的解决办法

    1.故障描述 这是运行在公有云上的一套Hadoop集群,有一个公网IP将部分服务的端口映射出来供办公室访问. 数据分析师报告说:在HUE上面浏览HDFS文件,点击"download" ...

  8. dmock 基于Django的轻量级Mock平台

    GitHub:https://github.com/yjlch1016/dmock # dmock 基于Django的轻量级Mock平台 dmock即Django+Mock的缩写 一.思路: mock ...

  9. instanceof读解

    function instance(l,r){ let 0 = r.prototype; let v = l.__proto__; while(true){ if(v === null){ retur ...

  10. You are my great sunshine

    "何为孤寂?" "清风,艳日,无笑意." "可否具体?" "左拥,右抱,无情欲." "可否再具体?" ...