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. 即将上线的Kafka服务器面临的一系列填坑笔记

      即将上线的Kafka服务器面临的一系列填坑笔记 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Kafka日志报错:[error] k.m.j.KafkaJMX$ - Fai ...

  2. python---wsgiref初探

    wsgiref使用 from wsgiref.simple_server import make_server from urls import URLS def RunServer(environ, ...

  3. Makefile 中符合的使用

    1. $@: 表示规则中的目标文件集.在模式规则中,如果有多个目标,那么,"$@"就是匹配于 目标中模式定义的集合 2. $^  : 所有的依赖目标的集合.以空格分隔.如果在依赖目 ...

  4. JAVA记录-JDBC介绍

    JDBC(Java DataBase Connection),java数据库连接,是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成 ...

  5. BIO | NIO | AIO (Java版)

    几篇解释的不错的文章: BIO NIO AIO NIO.2 入门,第 1 部分: 异步通道 API 使用异步 I/O 大大提高应用程序的性能

  6. CodeForces - 907A Masha and Bears

    A. Masha and Bears time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  7. centos7安装telnet

    yum list |grep telnet yum install telnet.x86_64 安装后再测试

  8. Windows句柄数限制

    设置 GDIProcessHandleQuota项设置GDI句柄数量,默认值为2710(16进制)/10000(10进制),该值的允许范围为 256 ~ 16384 ,将其调整为大于默认的10000的 ...

  9. [C++]数组与指针(纯代码-复习用)

    #include<iostream> #include<cmath> //C++ //#include<math.h> //C #include<ctime& ...

  10. 自定义滤镜 ColorMatrixFilter

    var url:URLRequest = new URLRequest("Koala.jpg"); var l:Loader = new Loader(); l.contentLo ...