算法讲解: KMP算法最浅显易懂
模板来源: 从头到尾彻底理解KMP

首先:KMP的模板为:

void get_next(char *a, int *nex) {
nex[] = ;
for (int i = , j = ; i <= len; i++) {
while (j > && a[i] != a[j + ])j = nex[j];
if (a[i] == a[j + ])j++;
nex[i] = j;
}
return;
} int KMP(char *a, char *b) {//b为母串
for (int i = , j = ; i <= strlen(b + ); i++) {
while (j > && (j == strlen(a + ) || b[i] != a[j + ]))j = nex[j];
if (b[i] == a[j + ])j++;
f[i] = j;
//若a在b中出现,,返回出现的位置
//if(f[i]==strlen(a+1)){return i-strlen(a);}
}
return ;
}

例题:2018 UESTC Training for Search Algorithm & String——L主楼

题意:求字符串中的最短循环节,并输出该循环节

KMP最小循环节、循环周期:
定理:假设S的长度为len,则S存在最小循环节,循环节的长度L为len-next[len],子串为S[0…len-next[len]-1]。
(1)如果len可以被len - next[len]整除,则表明字符串S可以完全由循环节循环组成,循环周期T=len/L。
(2)如果不能,说明还需要再添加几个字母才能补全。需要补的个数是循环个数L-len%L=L-(len-L)%L=L-next[len]%L,L=len-next[len]。

注意这里的len是原字符串的len+1;

 #include<cstdio>
#include<string.h>
#include<algorithm>
using namespace std;
int T, len;
char s[ + ];
int nex[ + ]; void get_next(char* p, int next[]){
int pLen = strlen(p) + ;//要求循环节长度时这里才+1
next[] = -;
int k = -;
int j = ;
while (j < pLen - ){
if (k == - || p[j] == p[k]){
++j;++k;
if (p[j] != p[k])
next[j] = k;
else
next[j] = next[k];
}
else{
k = next[k];
}
}
} int kmp(char* s, char* p){
int i = ;
int j = ;
int sLen = strlen(s);
int pLen = strlen(p);
while (i < sLen && j < pLen){
//①如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++
if (j == - || s[i] == p[j]){
i++;
j++;
}
else{
//②如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j]
//next[j]即为j所对应的next值
j = nex[j];
}
}
if (j == pLen)
return i - j;
else
return -;
} int main() {
scanf("%d", &T);
while (T--) {
memset(nex, , sizeof(nex));
scanf("%d", &len);
scanf("%s", s);
len = strlen(s);
get_next(s, nex);
printf("%d\n", len - nex[len]);
for (int i = ; i < len - nex[len]; i++)
printf("%c", s[i]);
printf("\n");
}
return ;
}

HDU1711(数字KMP)

 #include<cstdio>
#include<string.h>
#include<algorithm>
using namespace std;
int T, len;
int len1, len2;
int s1[ + ];
int s2[ + ];
int nex[ + ]; void get_next(int* p, int next[]) {
int pLen = len2;//要求循环节长度时这里才+1
next[] = -;
int k = -;
int j = ;
while (j < pLen - ) {
if (k == - || p[j] == p[k]) {
++j; ++k;
if (p[j] != p[k])
next[j] = k;
else
next[j] = next[k];
}
else {
k = next[k];
}
}
} int kmp(int* s, int* p) {
int i = ;
int j = ;
int sLen = len1;
int pLen = len2;
get_next(s2, nex);
while (i < sLen && j < pLen) {
//①如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++
if (j == - || s[i] == p[j]) {
i++;
j++;
}
else {
//②如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j]
//next[j]即为j所对应的next值
j = nex[j];
}
}
if (j == pLen)
return i - j;
else
return -;
} int main() {
scanf("%d", &T);
while (T--) {
scanf("%d %d", &len1, &len2);
for (int i = ; i < len1; i++)
scanf("%d", &s1[i]);
for (int i = ; i < len2; i++)
scanf("%d", &s2[i]);
if (kmp(s1,s2) == -)
printf("-1\n");
else
printf("%d\n", kmp(s1,s2)+);
}
return ;
}

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. 在Linux安装MySQL

    yum 方式卸载MySQL与安装MySQL . rpm -qa | grep -i mysql命令查看已经安装过的组件 [root@VM_0_10_centos ~]# rpm -qa | grep ...

  2. 手把手教你快速使用数据可视化BI软件创建全球经济贸易分析大屏

    灯果数据可视化BI软件是新一代人工智能数据可视化大屏软件,内置丰富的大屏模板,可视化编辑操作,无需任何经验就可以创建属于你自己的大屏.大家可以在他们的官网下载软件.   本文以全球经济贸易分析大屏为例 ...

  3. pikachu-服务器端请求伪造SSRF(Server-Side Request Forgery)

    一.SSRF概述(部分内容来自pikachu平台) SSRF(Server-Side Request Forgery:服务器端请求伪造),其形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功 ...

  4. ASP.NET MVC通用权限管理系统(响应布局)源码更新介绍

    一.asp.net mvc 通用权限管理系统(响应布局)源码主要以下特点: AngelRM(Asp.net MVC)是基于asp.net(C#)MVC+前端bootstrap+ztree+lodash ...

  5. Shiro -- (二) 身份验证基本流程

    简介: 在 shiro 中,用户需要提供 principals (身份)和 credentials(证明)给 shiro,从而应用能验证用户身份: principals:身份,即主体的标识属性,可以是 ...

  6. .net core 3 web api jwt 一直 401

    最近在给客户开发 Azure DevOps Exension, 该扩展中某个功能需要调用使用 .NET Core 3 写的 Web Api. 在拜读了 Authenticating requests ...

  7. kubernetes 资源管理

    前言 在kubernetes环境下,无论集群再大,对应的集群资源(cpu.memory.storage)总是有上限的.而默认情况下,我们启动的pod.以及pod中运行的容器,对应的资源是不加限制的.理 ...

  8. 得心应用的Vue高级技巧---vue中文社区

    1,require.context()一个webpack的api,通过执行require.context函数获取一个特定的上下文,主要用来实现自动化导入模块,在前端工程中,如果遇到从一个文件夹引入很多 ...

  9. POJ-2299 Ultra-QuickSort(用树状数组求逆序对数)

    题目链接 ac代码 #include<iostream> #include<cstdio> #include<cstring> #include<algori ...

  10. windows服务踩的坑

    最近写了一个windows服务 有一些bug最后终于解决了还是写点经验把. 第一点.版本问题,因为是小白,第一次写windows服务,选择的是.net4.6.1的目标框架,因为我的电脑是windows ...