目录

KMP

字符串匹配

最小循环覆盖

EXKMP

字符串匹配

Secret word

Password


KMP

模板

void kmp() {int m = strlen(p + 1);int j = 0;nxt[1] = 0;for (int i = 2; i <= m; ++i) {while (j && p[i] != p[j + 1])j = nxt[j];if (p[i] == p[j + 1])++j;nxt[i] = j;}
}

p[i]  与  p[j + 1]  作比较?

j是与i - 1的字符相匹配的。所以但我们计算i时,待匹配的是j + 1 这个位置的字符。

比如下方的第二个和第四个字符,都是b,他们是匹配的。i等于5之后,此时的j还是2,所以是i与j+1进行比较。

用来解决字符串的匹配问题,比如在文档中  Ctrl + F 去查找特定的内容。

需要清除nxt数组的含义:

a        b        a        b        a        c        m

0        0        1        2        3        0        0

nxt[i]  以i结尾的字符,与p字符串前缀最大匹配的长度

字符串匹配

// problem :  #include <bits/stdc++.h>
using namespace std;
#define ll long long
typedef pair<int, int> PII;
#define pb push_backchar s[100005], p[100005];
int nxt[100005], f[100005];
int n, m;
void solve() {scanf("%s%s", s + 1, p + 1);n = strlen(s + 1);m = strlen(p + 1);int j = 0;nxt[1] = 0;for (int i = 2; i <= m; ++i) {while (j && p[i] != p[j + 1])j = nxt[j];if (p[i] == p[j + 1])++j;nxt[i] = j;}j = 0;for (int i = 1; i <= n; ++i) {while (j == m || (j && s[i] != p[j + 1]))j = nxt[j];if (s[i] == p[j + 1])++j;f[i] = j;}int ans = 0;for (int i = 1; i <= n; ++i) {if (f[i] == m)ans++;}if (ans == 0) printf("-1\n-1\n");else {printf("%d\n", ans);for (int i = 1; i <= n; ++i) {if (f[i] == m) {printf("%d ", i - m + 1);}}puts("");}
}
int main(){int t; scanf("%d", &t);for (int i = 1; i <= t; ++i) {solve();}   return 0;
}

最小循环覆盖 

结论:m - nxt[m] 

nxt[m] 是以m为结尾的字符,与字符串p前缀匹配的最大长度。 

// problem :  #include <bits/stdc++.h>
using namespace std;
#define ll long long
typedef pair<int, int> PII;
#define pb push_backchar p[100005];
int nxt[100005];
void kmp() {int m = strlen(p + 1);int j = 0;nxt[1] = 0;for (int i = 2; i <= m; ++i) {while (j && p[i] != p[j + 1])j = nxt[j];if (p[i] == p[j + 1])++j;nxt[i] = j;}printf("%d\n", m - nxt[m]);
}
int main(){scanf("%s", p + 1);kmp();return 0;
}

EXKMP

拓展kmp,又称Z算法

模板:

void exkmp() {int n = strlen(s + 1);z[1] = 0;int L = 1, R = 0;for (int i = 2; i <= n; ++i) {if (i > R) {z[i] = 0;} else {int k = i - L + 1;z[i] = min(z[k], R - i + 1);}while (i + z[i] <= n && s[z[i] + 1] == s[i + z[i]])++z[i];if (i + z[i] - 1 > R) {L = i, R = i + z[i] - 1;}}
}

z[i]  : 从i开始的字符串与s字符串前缀最大匹配的长度

字符串匹配

// problem :  #include <bits/stdc++.h>
using namespace std;
#define ll long long
typedef pair<int, int> PII;
#define pb push_back
const int N = 200005;
char s[N], p[N];
int z[N];
int n, m;void solve() {scanf("%s%s", s + 1, p + 1);n = strlen(s + 1);m = strlen(p + 1);p[m + 1] = '#';for (int i = m + 2, j = 1; j <= n; ++i, ++j) {p[i] = s[j];}z[1] = 0;int L = 1, R = 0;for (int i = 2; i <= n + m + 1; ++i) {if (i > R) {z[i] = 0;} else {int k = i - L + 1;z[i] = min(z[k], R - i + 1);}while (i + z[i] <= n + m + 1 && p[z[i] + 1] == p[i + z[i]])++z[i];if (i + z[i] - 1 > R) {L = i, R = i + z[i] - 1;}}int ans = 0;for (int i = m + 2; i <= n + m + 1; ++i) {if (z[i] == m) ans++;}if (ans == 0) puts("-1\n-1");else {printf("%d\n", ans);for (int i = m + 2; i <= n + m + 1; ++i) {if (z[i] == m) {printf("%d ", i - m - 1);}}puts("");}
}
int main(){int t; scanf("%d", &t);while (t--) {solve();}return 0;
}

Secret word 

// problem :  #include <bits/stdc++.h>
using namespace std;
#define ll long long
typedef pair<int, int> PII;
#define pb push_backconst int N = 1E5 + 5;
char s[N << 1];
int z[N << 1];void solve() {int n = strlen(s + 1);s[n + 1] = '#';for (int i = n + 2, j = n; j ; --j, ++i) {s[i] = s[j];}z[1] = 0;int L = 1, R = 0;for (int i = 2; i <= 2 * n + 1; ++i) {if (i > R) {z[i] = 0;} else {int k = i - L + 1;z[i] = min(z[k], R - i + 1);}while (i + z[i] <= 2 * n + 1 && s[z[i] + 1] == s[i + z[i]])++z[i];if (i + z[i] - 1 > R) {L = i, R = i + z[i] - 1;}}int ans = 0;for (int i = n + 2; i <= 2 * n + 1; ++i) {ans = max(ans, z[i]);}for (int i = ans; i >= 1; --i)printf("%c", s[i]);putchar(10);
}
int main(){scanf("%s", s + 1);solve();return 0;
}

Password

#include <bits/stdc++.h>
using namespace std;
#define ll long long
typedef pair<int, int> PII;
#define pb push_back
const int N = 1000005;
char s[N], p[N];
int z[N];
int n, m;void solve() {scanf("%s", s + 1);n = strlen(s + 1);z[1] = 0;int L = 1, R = 0;for (int i = 2; i <= n; ++i) {if (i > R) {z[i] = 0;} else {int k = i - L + 1;z[i] = min(z[k], R - i + 1);}while (i + z[i] <= n && s[z[i] + 1] == s[i + z[i]])++z[i];if (i + z[i] - 1 > R) {L = i, R = i + z[i] - 1;}}int ans = 0, x = 0;for (int i = 1; i <= n; ++i) {if (z[i] == n - i + 1) {if (x >= z[i])ans = max(ans, z[i]);}x = max(x, z[i]);}if (!ans) printf("Just a legend\n");else {for (int i = 1; i <= ans; ++i)printf("%c", s[i]);puts("");}
}
int main(){solve();return 0;
}

KMP / EXKMP相关推荐

  1. [算法讲解] KMP EXKMP : next与extend的羁绊

    KMP KMP作为一个广为人知的字符串匹配算法--也是本文的前一半. 旨在着重讲解next数组的求法,并使读者理解. 先扔代码 luoguP3375 [模板]KMP字符串匹配 #include< ...

  2. SZUACM集训字符串基础总结: 字符串最小表示 ,KMP, EXKMP, Manracher, Trie树,字符串的hash; 附带一写常见的运用技巧,邝斌大佬的板子和例题[持续更新]

    第一部分 字符串的匹配<-------->KMP 模式匹配:子串的定位运算称为串的模式匹配或串匹配. 假设有两个串S,T,设S为主串,也称正文串,T为子串,也称为模式,在主串S中查找与模式 ...

  3. 近期将要学习的内容(flag)

    块状链表 左偏树 最大流,最小割 费用流 数位DP 计算几何 主席树 树套树(弃疗) 斜率优化 manacher kmp,exkmp 树链剖分 splay树(只看了理论) Trie树 线段树操作及应用 ...

  4. 算法笔记--KMP算法 EXKMP算法

    1.KMP算法 这个博客写的不错:http://www.cnblogs.com/SYCstudio/p/7194315.html 模板: next数组的求解,那个循环本质就是如果相同前后缀不能加上该位 ...

  5. 数据结构--KMP算法总结

    数据结构-KMP KMP算法用于解决两个字符串匹配的问题,但更多的时候用到的是next数组的含义,用到next数组的时候,大多是题目跟前后缀有关的 . 首先介绍KMP算法:(假定next数组已经学会, ...

  6. 嫦娥奔月(KMP,找循环节)及其扩展KMP

    问题描述 <归妹>卦辞为:昔者恒我(姮娥)窃毋死之药于西王母,服之以(奔)月.将往,而枚占于有黄.有黄占之曰:"吉.翩翩归妹,独将西行.逢天晦芒,毋惊毋恐,后且大昌". ...

  7. HDU - 4333 Revolving Digits(扩展KMP)

    题目链接:点击查看 题目大意:给出一个由 n 个数位组成的数字,现在可以通过将其不同的后缀移到前面来组成 n 个新的数字,现在要求出 n 个新数字进行去重后,有多少个新数字分别大于.等于.小于原数字 ...

  8. HDU - 4300 Clairewd’s message(扩展KMP)

    题目链接:点击查看 题目大意:给出两个字符串 s 和 t ,字符串 s 代表着一种密码的映射,字符串 t 代表着一段密文+明文,题目保证密文是完整的,但明文只有一部分,现在问如何补全字符串 t ,使得 ...

  9. HDU - 6629 string matching(扩展KMP)

    题目链接:点击查看 题目大意:给出一个字符串 s 和一个暴力程序,用于求解 s 的每个后缀和原字符串的最长公共前缀,现在问一共需要执行多少次比较操作 题目分析:首先肯定不能暴力去模拟,时间复杂度n*n ...

最新文章

  1. gitter 卸载_最佳Gitter频道:Scala
  2. poj2352(树状数组)
  3. python中列表数据汇总和平均值_对数据进行分类,计算每个类别的平均值和标准差...
  4. java method 创建_java中创建对象的5种方式
  5. 如何打开手机端口_微信接收图纸dwg怎么打开?如何手机查看CAD图纸,三步免费教你...
  6. go 随机数是重复的
  7. 查看服务器是有有默认共享文件,服务器共享文件远程查看
  8. SpringBoot : BeanFactory
  9. 专业测评:5款热门的免费报表软件
  10. SAP软件财务年结步骤
  11. 基于视觉的移动平台运动目标检测
  12. 200以后最小质数:
  13. iOS系统下常用的三方应用URL Scheme值
  14. Jointly Learning Explainable Rules for Recommendation with Knowledge Graph
  15. 2022年CISP证书有啥用
  16. 爱马仕手表如何鉴别真假?
  17. 普乐蛙VR航天体验|航天vr设备|航空vr设备厂家案例分享
  18. 乐吾乐2D可视化为智慧电力赋能(二)
  19. Ceph部署、基本使用和与OpenStack的集成
  20. 电解电容为什么会爆炸?

热门文章

  1. DVWA之Insecure Captcha
  2. java小括号报错_JAVA新人常犯错误集锦
  3. 监控宝 mysql_使用监控宝监控你的Linux服务器(附图)
  4. 【windows-教程】打开telnet客户端功能
  5. IP地址-子网掩码-默认网关
  6. win10网络中看不到其他共享计算机,但能通过 “计算机名+\\”访问的问题
  7. 使用又拍云加速你的静态网站
  8. android studio 好用的加载等待提示框 LoadingDialog
  9. com.wis.view.CircleImageview cannot be cast to com.wis.view.ClipViewLayout
  10. 菜鸟mysql四分钟导入千万级别的数据