KMP 算法

KMP 算法是一种改进的字符串匹配算法,KMP 算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是实现一个next()函数,函数本身包含了模式串的局部匹配信息。时间复杂度 O(m+n)O(m+n)O(m+n)。

朴素做法

你有两个串 ababbabaaba,求第二个串在第一个串中出现了多少次。





















设两串的长度分别为 n,mn,mn,m,则时间复杂度 O(nm)O(nm)O(nm)。

我们看到,标 ☆ 的几步可以优化。那应该怎么优化呢?

next 数组

我们发现,当一个串匹配失败时,不总是需要再次从头开始匹配。如果这个串有公共的前后缀,那么可以节约时间。

那我们就在这方面下点功夫。设 next[x]next[x]next[x] 表示这个串前 xxx 位的公共的前后缀的最大长度,且 next[x]&lt;xnext[x]&lt;xnext[x]<x,x∈[1,len]x\in[1,len]x∈[1,len],lenlenlen 表示这个串的长度。

以下为求 nextnextnext 数组的步骤。

定义两个指针 i=2,j=0i=2,j=0i=2,j=0。



因为 str[i]≠str[j+1]str[i]\neq str[j+1]str[i]̸​=str[j+1],且 j=0j=0j=0,所以 next[i]=next[2]=0next[i]=next[2]=0next[i]=next[2]=0。



因为 str[i]=str[j+1]str[i]=str[j+1]str[i]=str[j+1],匹配成功。所以将 jjj 指针右移一位,next[i]=j+1next[i]=j+1next[i]=j+1。

匹配成功,jjj 右移一位。

匹配失败,令 j=next[j]j=next[j]j=next[j],继续判定。

仍然无法配对。因此 next[i]=0next[i]=0next[i]=0。





luogu P3375

#include<cstdio>
#include<cstdlib>
#include<cstring> #define reg register int next[1000010];
char str1[1000010],str2[1000010];
int len1,len2,t=0; int main(){
memset(next,0,sizeof(next));
scanf("%s%s",str1+1,str2+1);
len1=strlen(str1+1);len2=strlen(str2+1);
for(reg int i=2;i<=len2;++i){
while(t>0&&str2[t+1]!=str2[i]) t=next[t];
if(str2[t+1]==str2[i]) ++t;
next[i]=t;
}
t=0;
for(reg int i=1;i<=len1;++i){
while(t>0&&str2[t+1]!=str1[i])t=next[t];
if(str2[t+1]==str1[i]) ++t;
if(t==len2) printf("%d\n",i-t+1);
}
for(reg int i=1;i<=len2;++i)
printf("%d ",next[i]);
}

loj 10043

#include<cstdio>
#include<cstdlib>
#include<cstring> #define reg register char str[1010],s[1010];
int next[1010];
int t=0,l,len;
int ans; int main(){
do{
scanf("%s",str+1);
if(str[1]=='#'&&str[2]=='\0') break;
scanf("%s",s+1);
l=strlen(str+1);len=strlen(s+1);
memset(next,0,sizeof(next));
t=ans=0;
for(int i=2;i<=len;++i){
while(t>0&&s[t+1]!=s[i]) t=next[t];
if(s[t+1]==s[i]) ++t;
next[i]=t;
}
t=0;
for(int i=1;i<=l;++i){
while(t>0&&s[t+1]!=str[i]) t=next[t];
if(s[t+1]==str[i]) ++t;
if(t==len) ++ans,t=0;
}
printf("%d\n",ans);
}while(1);
}

KMP算法复习笔记的更多相关文章

  1. KMP算法复习【+继续学习】

    离NOIP还剩12天,本蒟蒻开始准备复习了. 先来个KMP[似乎我并没有写过KMP的blog] KMP KMP算法是解决字符串匹配问题的一个算法,主要是单对单的字符串匹配加速,时间复杂度O(m + n ...

  2. Java基础复习笔记基本排序算法

    Java基础复习笔记基本排序算法 1. 排序 排序是一个历来都是很多算法家热衷的领域,到现在还有很多数学家兼计算机专家还在研究.而排序是计算机程序开发中常用的一种操作.为何需要排序呢.我们在所有的系统 ...

  3. 笔记-算法-KMP算法

    笔记-算法-KMP算法 1.      KMP算法 KMP算法是一种改进的字符串匹配算法,KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的.具体实现就是实现一 ...

  4. 串的应用与kmp算法讲解--学习笔记

    串的应用与kmp算法讲解 1. 写作目的 平时学习总结的学习笔记,方便自己理解加深印象.同时希望可以帮到正在学习这方面知识的同学,可以相互学习.新手上路请多关照,如果问题还请不吝赐教. 2. 串的逻辑 ...

  5. 算法笔记之KMP算法

    本文是<算法笔记>KMP算法章节的阅读笔记,文中主要内容来源于<算法笔记>.本文主要介绍了next数组.KMP算法及其应用以及对KMP算法的优化. KMP算法主要用于解决字符串 ...

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

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

  7. 学习笔记-KMP算法

    按照学习计划和TimeMachine学长的推荐,学习了一下KMP算法. 昨晚晚自习下课前粗略的看了看,发现根本理解不了高端的next数组啊有木有,不过好在在今天系统的学习了之后感觉是有很大提升的了,起 ...

  8. 数据结构(复习)---------字符串-----KMP算法(转载)

    字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD" ...

  9. KMP算法_读书笔记

    下面是KMP算法的实现伪代码: KMP_MATCHER ( T, P ) . n = T.length . m = P.length . next = COMPUTE_PREFIX_FUNCTION ...

随机推荐

  1. 手把手教程: CentOS 6.5 LVS + KeepAlived 搭建 负载均衡 高可用 集群

    为了实现服务的高可用和可扩展,在网上找了几天的资料,现在终于配置完毕,现将心得公布处理,希望对和我一样刚入门的菜鸟能有一些帮助. 一.理论知识(原理) 我们不仅要知其然,而且要知其所以然,所以先给大家 ...

  2. ios打包时候提示三方文件库错误,整理下解决的思路

    这一短时间一直在打包APP上线,今天突然打包的时候碰到的头文件找不到 一开始我以为是路径的问题,检查了targets---Build settings----search Paths----heade ...

  3. 自定义View入门-绘制基础(1)

    ### 前言 说道自定义View,我们一定会想到,自定义View的绘制流程 - 测量阶段(measure) - 布局阶段(layout) - 绘制阶段(draw) 我们看到的一些炫酷的view效果,都 ...

  4. TCGA各种肿瘤数据的20多种不同玩法/挖掘方法

    肿瘤基因组图谱 (The Cancer Genome Atlas,TCGA) 计划是由美国国家癌症研究院(National Cancer Institute,NCI)和美国国家人类基因组研究所(Nat ...

  5. 【转】在Linux下搭建Git服务器

    在 Linux 下搭建 Git 服务器 环境: 服务器 CentOS6.6 + git(version 1.7.1)客户端 Windows10 + git(version 2.8.4.windows. ...

  6. 品Spring:能工巧匠们对注解的“加持”

    问题的描述与方案的提出 在Spring从XML转向注解时,为了自身的开发方便,对注解含义进行了扩充(具体参考本号上一篇文章). 这个扩充直接导致了一个问题,就是需要从注解往元注解以及元元注解(即沿着从 ...

  7. java Swing 界面化查询数据库表

    两天从0基础写的.没有按钮对话框功能,只是简单的实现. 当然代码上有很多需要优化的,基本需要重写哈哈哈.但是我怕以后有需要所以还是存一下好了.<把RS结果集,放vector里面,用vector构 ...

  8. Hadoop点滴-HDFS文件系统

    1.HDFS中,目录作为元数据,保存在namenode中,而非datanode中 2.HDFS的文件权限模型与POSIX的权限模式非常相似,使用  r  w  x 3.HDFS的文件执行权限(X)可以 ...

  9. Scala Eclipse org.eclipse.e4.workbench异常奔溃修复

     Scala Eclipse org.eclipse.e4.workbench异常奔溃修复: 找到<workspace>/.metadata/.plugins/org.eclipse.e4 ...

  10. Scala 多继承顺序

    Trait多继承顺序: 准则: 如果有超类,则先调用超类的函数. 如果混入的trait有父trait,它会按照继承层次先调用父trait的构造函数. 如果有多个父trait,则按顺序从左到右执行. 所 ...