next数组的含义:next[i]表示以字符串s的第i个字符为结尾的后缀与s前缀匹配的长度

next数组也可以当做fail数组,即当模式串s[j]与串t[i]不匹配时,只要将j转换到next[j]继续匹配即可

  在求s的next数组时,也用同样的原理,当s[j]与s[i]不匹配时,只要将j转换到next[j]继续匹配即可,当 注意此时模式串的首字母是s[0]

poj3461

//next[i]表示和模式串第i位匹配失败时,再去和模式串第next[i]位匹配
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
char s[],t[];
int tot,nxt[];
void kmp_pre(){
int i,j;
int len=strlen(s);
j=nxt[]=-;i=;
while(i<len){
while(j!=- && s[i]!=s[j]) j=nxt[j];
nxt[++i]=++j;
}
}
void kmp(){
int i,j,ans;
int m=strlen(s);
int n=strlen(t);
i=j=ans=;
while(i<n){
while(j!=- && t[i]!=s[j]) j=nxt[j];
++i,++j;
if(j==m){
ans++;
j=nxt[j];
}
}
printf("%d\n",ans);
}
int main(){
int tt;
scanf("%d",&tt);
while(tt--){
memset(nxt,,sizeof nxt);
scanf("%s%s",s,t);
kmp_pre();
kmp();
}
}

hdu1711 求最左边匹配位

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define maxn 1000005
int nxt[maxn],a[maxn],b[maxn],n,m;
void kmp_pre(){
memset(nxt,,sizeof nxt);
int i,j;
i=;j=nxt[]=-;
while(i<m){
while(j!=- && b[i]!=b[j])j=nxt[j];
nxt[++i]=++j;
}
}
void kmp(){
int i,j,ans;
i=j=ans=;
while(i<n){
while(j!=- && a[i]!=b[j])j=nxt[j];
++i;++j;
if(j==m){
printf("%d\n",i-j+);
return;
}
}
puts("-1");
return;
}
int main(){
int t;
cin >> t;
while(t--){
scanf("%d%d",&n,&m);
for(int i=;i<n;i++)scanf("%d",&a[i]);
for(int i=;i<m;i++)scanf("%d",&b[i]);
kmp_pre();
kmp();
}
}

poj1961 求循环节

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define maxn 1000005 int m,nxt[maxn];
char s[maxn];
void kmp_pre(){
memset(nxt,,sizeof nxt);
int i,j;
i=;j=nxt[]=-;
while(i<m){
while(j!=- && s[i]!=s[j])j=nxt[j];
nxt[++i]=++j;
}
} int main(){
int tt=;
while(scanf("%d",&m),m){
printf("Test case #%d\n",++tt);
scanf("%s",s);
kmp_pre();
for(int i=;i<=m;i++){
if(i%(i-nxt[i])== && i/(i-nxt[i])>)
printf("%d %d\n",i,i/(i-nxt[i]));
}
puts("");
}
}

poj2406 求最小循环节

//如果将s数组右移一维,那么nxt[i]就是:后缀s[i]与s前缀匹配的长度
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define maxn 1000005 int m,nxt[maxn];
char s[maxn]; void kmp_pre(){
memset(nxt,,sizeof nxt);
m=strlen(s);
int i,j;
i=;j=nxt[]=-;
while(i<m){
while(j!=- && s[i]!=s[j])j=nxt[j];
nxt[++i]=++j;
}
} int main(){
while(scanf("%s",s)&&strcmp(s,".")){
kmp_pre();
int ans=;
if(m%(m-nxt[m])==)ans=m/(m-nxt[m]);
printf("%d\n",ans);
} }

hdu3336 next数组+线性dp

//cnt[i]表示以s[i]结尾的串可以匹配的前缀数
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define mod 10007
#define maxn 200005 int m,t,nxt[maxn];
char s[maxn];
void kmp_pre(){
memset(nxt,,sizeof nxt);
int i,j;
i=;j=nxt[]=-;
while(i<m){
while(j!=- && s[i]!=s[j])j=nxt[j];
nxt[++i]=++j;
}
} int main(){
scanf("%d",&t);
while(t--){
scanf("%d%s",&m,s);
kmp_pre();
int ans=,cnt[maxn]={};
cnt[]=,cnt[]=;
for(int i=;i<=m;i++)
cnt[i]=(cnt[nxt[i]]+)%mod;
for(int i=;i<=m;i++)ans=(ans+cnt[i])%mod;
printf("%d\n",ans);
}
}

*hdu3746 循环节应用

/*
最小循环节=串长-末位匹配长度
*/#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define maxn 100005 int nxt[maxn],m;
char s[maxn];
void pre_kmp(){
memset(nxt,,sizeof nxt);
m=strlen(s);
int i,j;
i=;j=nxt[]=-;
while(i<m){
while(j!=- && s[i]!=s[j])j=nxt[j];
nxt[++i]=++j;
}
} int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%s",s);
pre_kmp();
if(nxt[m]==)printf("%d\n",m);
else if(m%(m-nxt[m])==)puts("");
else {
int cir=m-nxt[m];
printf("%d\n",cir-nxt[m]%cir);
}
}
}

*hdu2594 后缀套后缀

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define maxn 50005
char s1[maxn<<],s2[maxn<<];
int n,m,nxt[maxn<<]; void kmp_pre(){
memset(nxt,,sizeof nxt);
int len=strlen(s1);
int i=,j=-;
nxt[]=-;
while(i<len){
while(s1[i]!=s1[j] && j!=-)
j=nxt[j];
nxt[++i]=++j;
}
}
int main(){
while(~scanf("%s%s",s1,s2)){
n=strlen(s1);
m=strlen(s2);
int minlen=min(n,m);
strcat(s1,s2);
kmp_pre(); int len=strlen(s1),ans=nxt[len];
if(ans==){
printf("0\n");
continue;
}
else {
while(ans>minlen)
ans=nxt[ans];
char tmp[maxn]={};
strncpy(tmp,s1,ans);
printf("%s %d\n",tmp,ans);
}
}
return ;
}

kmp算法专题总结的更多相关文章

  1. 字符串专题之KMP算法

    写点自己对KMP的理解,我们有两个字符串A和B,求A中B出现了多少次. 这种问题就可以用KMP来求解. 朴素的匹配最坏情况是O(n^2)的.KMP是个高效的算法,效率是O(n)的. KMP算法的思想是 ...

  2. 算法数据结构 | 只要30行代码,实现快速匹配字符串的KMP算法

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是算法数据结构专题的第29篇文章,我们来聊一个新的字符串匹配算法--KMP. KMP这个名字不是视频播放器,更不是看毛片,它其实是由Kn ...

  3. 算法专题 | 10行代码实现的最短路算法——Bellman-ford与SPFA

    今天是算法数据结构专题的第33篇文章,我们一起来聊聊最短路问题. 最短路问题也属于图论算法之一,解决的是在一张有向图当中点与点之间的最短距离问题.最短路算法有很多,比较常用的有bellman-ford ...

  4. 简单有效的kmp算法

    以前看过kmp算法,当时接触后总感觉好深奥啊,抱着数据结构的数啃了一中午,最终才大致看懂,后来提起kmp也只剩下“奥,它是做模式匹配的”这点干货.最近有空,翻出来算法导论看看,原来就是这么简单(先不说 ...

  5. KMP算法

    KMP算法是字符串模式匹配当中最经典的算法,原来大二学数据结构的有讲,但是当时只是记住了原理,但不知道代码实现,今天终于是完成了KMP的代码实现.原理KMP的原理其实很简单,给定一个字符串和一个模式串 ...

  6. 萌新笔记——用KMP算法与Trie字典树实现屏蔽敏感词(UTF-8编码)

    前几天写好了字典,又刚好重温了KMP算法,恰逢遇到朋友吐槽最近被和谐的词越来越多了,于是突发奇想,想要自己实现一下敏感词屏蔽. 基本敏感词的屏蔽说起来很简单,只要把字符串中的敏感词替换成"* ...

  7. KMP算法实现

    链接:http://blog.csdn.net/joylnwang/article/details/6778316 KMP算法是一种很经典的字符串匹配算法,链接中的讲解已经是很明确得了,自己按照其讲解 ...

  8. 数据结构与算法JavaScript (五) 串(经典KMP算法)

    KMP算法和BM算法 KMP是前缀匹配和BM后缀匹配的经典算法,看得出来前缀匹配和后缀匹配的区别就仅仅在于比较的顺序不同 前缀匹配是指:模式串和母串的比较从左到右,模式串的移动也是从 左到右 后缀匹配 ...

  9. 扩展KMP算法

    一 问题定义 给定母串S和子串T,定义n为母串S的长度,m为子串T的长度,suffix[i]为第i个字符开始的母串S的后缀子串,extend[i]为suffix[i]与字串T的最长公共前缀长度.求出所 ...

随机推荐

  1. 内置窗口 pyqt5

    1.使用Qt Designer设计三个窗口 注意:在主窗口中需要添加一个girdLayout 2.创建**.py from PyQt5.QtWidgets import QMainWindow, QA ...

  2. 即将上线的flume服务器面临的一系列填坑笔记

      即将上线的flume服务器面临的一系列填坑笔记 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.   一.flume缺少依赖包导致启动失败! 报错信息如下: 2018-10-17 ...

  3. VBScript进阶篇一

    VBScript进阶篇一       作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.编译型与解释型的区别 其实我们通过一张图就可以大致了解一下,他们运行机制. 想要了解更多,请 ...

  4. 面向对象【day07】:新式类和经典类(八)

    本节内容 1.概述 2.类的多继承 3.经典类VS新式类 4.总结 一.概述 在python还支持多继承,但是一般我们很少用,有些语言干脆就不支持多继承,有多继承,就会带来两个概念,经典类和新式类,下 ...

  5. ElasticSearch 例子

    ElasticSearch是一个接近实时的搜索平台,它利用Lucese进行文档索引. 本文会写个可以运行的简单例子,方便大家上手,日后深入了解. 需要引入maven依赖 <dependency& ...

  6. 设计模式---组件协作模式之观察者模式(Observer)

    一:概念 Observer模式的作用是当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态 Observer模式提供给关联对象一种同步通信的手段,使得某个对象与依赖他的其他对象之间保 ...

  7. div显示提示信息【转】

    div显示提示信息 <body> <style type="text/css"> a.link{position:relative;} a.link div ...

  8. PHP 进行支付宝开发中return_url和notify_url的区别分析

    在支付宝处理业务中return_url,notify_url是返回些什么状态呢,我们要根据它来做一些处理就必须了解return_url,notify_url的区别,下面我就来给大家介绍; 一.问题描述 ...

  9. java基本数据类型,访问控制符,运算符执行顺序

    1.java数据类型 内置数据类型:boolean(1),  byte(8), char(16), short(8), int(32), long(64), float(32), double(64) ...

  10. Docker 入门 第六部分:部署app

    目录 Docker 入门 第六部分:部署app 先决条件 介绍 选择一个选项 Docker CE(Cloud provider) Enterprise(Cloud provider)这里不做介绍 En ...