算法讲解: 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. 杭电-------2043密码(C语言写)

    #include<stdio.h> #include<string.h> ]; ] = { '~','!','@','#','$','%','^' }; ] = { }; in ...

  2. Qt Python Scriptable Application

    Qt Python Scriptable Application eryar@163.com Abstract. Python and C++ are in many ways as differen ...

  3. Windows安装node环境,部署静态网站

    1.进入官网,下载nodejs https://nodejs.org/zh-cn/ 2.安装nodejs win10怎么安装nodejs和npm https://jingyan.baidu.com/a ...

  4. 在Docker中运行SpringBoot程序

    1.将SpringBoot项目中pom.xml的build插件更换为: <build> <plugins> <plugin> <groupId>org. ...

  5. 带输入提示的搜索框ajax请求

    先放图 首先要引用的文件有: base.css  https://www.cnblogs.com/chenyingying0/p/12363689.html jquery.js transition. ...

  6. Linux中screen命令

    screen是一款由GNU计划开发的用于命令行终端切换的自由软件.用户可以通过该软件同时连接多个本地或远程的命令行会话,并在其间自由切换.GNU Screen可以看作是窗口管理器的命令行界面版本.它提 ...

  7. python基础练习,循环、列表、字典、数组

    # encoding: utf-8 ''' @author: mark @file: 20200214.py @time: 2020/2/14 14:21 @software: PyCharm ''' ...

  8. Integer使用==做判断遇到的问题

    问题: 最近使用Integer类型的数据做判断时,遇到了一个神奇的问题. 如: Integer a=223; Integer b=223; 这样使用==做判断,得到的结果是 false 原因: 后来查 ...

  9. 在香蕉派的树莓派系统上配置 Syncthing 自启动

    在香蕉派的树莓派系统上配置 Syncthing 自启动 —— 魏刘宏 2020 年 1 月 19 日 首先做个名词解释,” 香蕉派” 是国内一款山寨树莓派的硬件产品,” 树莓派系统” 指的是”rasp ...

  10. Python小白

      .IDLE软件为内建于CPython的集成开发环境(IDE),包括编辑器,编译或解释器,调试器       .py(后缀保存) 2.行一,单行注释     多行,”””    ‘’’  之后,内建 ...