kmp算法专题总结
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算法专题总结的更多相关文章
- 字符串专题之KMP算法
写点自己对KMP的理解,我们有两个字符串A和B,求A中B出现了多少次. 这种问题就可以用KMP来求解. 朴素的匹配最坏情况是O(n^2)的.KMP是个高效的算法,效率是O(n)的. KMP算法的思想是 ...
- 算法数据结构 | 只要30行代码,实现快速匹配字符串的KMP算法
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是算法数据结构专题的第29篇文章,我们来聊一个新的字符串匹配算法--KMP. KMP这个名字不是视频播放器,更不是看毛片,它其实是由Kn ...
- 算法专题 | 10行代码实现的最短路算法——Bellman-ford与SPFA
今天是算法数据结构专题的第33篇文章,我们一起来聊聊最短路问题. 最短路问题也属于图论算法之一,解决的是在一张有向图当中点与点之间的最短距离问题.最短路算法有很多,比较常用的有bellman-ford ...
- 简单有效的kmp算法
以前看过kmp算法,当时接触后总感觉好深奥啊,抱着数据结构的数啃了一中午,最终才大致看懂,后来提起kmp也只剩下“奥,它是做模式匹配的”这点干货.最近有空,翻出来算法导论看看,原来就是这么简单(先不说 ...
- KMP算法
KMP算法是字符串模式匹配当中最经典的算法,原来大二学数据结构的有讲,但是当时只是记住了原理,但不知道代码实现,今天终于是完成了KMP的代码实现.原理KMP的原理其实很简单,给定一个字符串和一个模式串 ...
- 萌新笔记——用KMP算法与Trie字典树实现屏蔽敏感词(UTF-8编码)
前几天写好了字典,又刚好重温了KMP算法,恰逢遇到朋友吐槽最近被和谐的词越来越多了,于是突发奇想,想要自己实现一下敏感词屏蔽. 基本敏感词的屏蔽说起来很简单,只要把字符串中的敏感词替换成"* ...
- KMP算法实现
链接:http://blog.csdn.net/joylnwang/article/details/6778316 KMP算法是一种很经典的字符串匹配算法,链接中的讲解已经是很明确得了,自己按照其讲解 ...
- 数据结构与算法JavaScript (五) 串(经典KMP算法)
KMP算法和BM算法 KMP是前缀匹配和BM后缀匹配的经典算法,看得出来前缀匹配和后缀匹配的区别就仅仅在于比较的顺序不同 前缀匹配是指:模式串和母串的比较从左到右,模式串的移动也是从 左到右 后缀匹配 ...
- 扩展KMP算法
一 问题定义 给定母串S和子串T,定义n为母串S的长度,m为子串T的长度,suffix[i]为第i个字符开始的母串S的后缀子串,extend[i]为suffix[i]与字串T的最长公共前缀长度.求出所 ...
随机推荐
- svg标签
在页面上画图无非有两种方法,一种是canvas,另外一种就是svg了,canvas之前已经介绍过了,现在来介绍一下svg吧. 其实早在svg出现以前几年,微软已经推出了类似的东西,叫做vml,早期是为 ...
- JVM总结(六):早期(编译期)优化
这节我们来总结一下JVM编译器优化问题. JVM编译器优化 Javac编译器 Javac的源码和调试 解析与填充符号表 注解处理器 语法分析与字节码生成 Java语法糖 泛型和类型擦除 自动装箱.拆箱 ...
- springboot整合activiMQ
首先说明: 队列queue 的特点就是,许多人可以监听它,但是只有一个人能够收到消息. 主题topic 的特点就是,许多人监听它,都能收到消息. 需要安装activiMQ在自己的电脑上.启动方 ...
- Linux记录-TCP状态以及(TIME_WAIT/CLOSE_WAIT)分析(转载)
1.TCP握手定理 2.TCP状态 l CLOSED:初始状态,表示TCP连接是“关闭着的”或“未打开的”. l LISTEN :表示服务器端的某个SOCKET处于监听状态,可以接受客户端的连接. ...
- 常用关于Android活动的实践技巧
//知晓当前是在哪一个活动 /* 新建一个BaseActivity类(Java class), 继承自AppCompatActivity * 重写 onCreate()方法,已有的活动无需再继承自Ap ...
- HITS算法--从原理到实现
本文介绍HITS算法的相关内容. 1.算法来源 2.算法原理 3.算法证明 4.算法实现 4.1 基于迭代法的简单实现 4.2 MapReduce实现 5.HITS算法的缺点 6.写在最后 参考资料 ...
- 搭建Linux下Android程序开发环境
从AndroidStudio中文社区下载SDK压缩包,http://dl.google.com/android/android-sdk_r24.2-linux.tgz. 解压到某个目录,比如我的~/p ...
- u-boot移植(十二)---代码修改---支持DM9000网卡
一.准备工作 1.1 原理图 CONFIG_DM9000_BASE 片选信号是接在nGCS4引脚,若要确定网卡的基地址,则要根据片选信号的接口去确定. 在三星2440的DATASHEET中memory ...
- OpenCV不同类型Mat的at方法访问元素时该如何确定模板函数的typename(转)
自从OpenCV推出了Mat后越来越像是Matlab了,使用起来方便了很多,但是,在用at方法访问Mat时,如何选用合适的typename类型来访问相应的Mat元素是个头疼的问题. 比如: int H ...
- [C++]线性链表之顺序表<二>
/* @content 线性链表之顺序表 @date 2017-3-21 1:06 @author Johnny Zen */ /* 线性表 顺序表 链式表[带头指针/不 ...