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. Mysql高手系列 - 第11篇:深入了解连接查询及原理

    这是Mysql系列第11篇. 环境:mysql5.7.25,cmd命令中进行演示. 当我们查询的数据来源于多张表的时候,我们需要用到连接查询,连接查询使用率非常高,希望大家都务必掌握. 本文内容 笛卡 ...

  2. Driect3D初始化演示

    初始化Direct3D演示 初始化Driect3D类: #include "Common\d3dApp.h" #include <DirectXColors.h> us ...

  3. springboot之全局处理异常封装

    springboot之全局处理异常封装 简介 在项目中经常出现系统异常的情况,比如NullPointerException等等.如果默认未处理的情况下,springboot会响应默认的错误提示,这样对 ...

  4. node项目的基本目录结构

    1.public目录: 项目公共目录,存放静态资源(img.js.css)和公共资源,404错误提示页面: 2.routor目录: 路由控制器目录,存放路由文件,将所有的业务逻辑都都写在这里: 3.v ...

  5. adb命令整理(持续整理)

    用到过的adb命令都整理下来,省的一直百度,还不一定能找到合适的答案 获得正在运行app的包名 :adb shell dumpsys window | findstr mCurrentFocus 1. ...

  6. Python 为什么要保留显式的 self ?

    花下猫语:前两天,我偶然在一个知识星球(刘欣老师的"码农翻身")里看到一篇主题,刘老师表示 Python 的类方法非要带个 self,而不像其它语言那样隐藏起来,这让人很不爽.我对 ...

  7. linux初学者小记

    a开头的小命令 alias命令 # echo=' - - - ' > /sys/class/scsi_host/host0/scan这条命令是咱们在给虚拟机装了一块新的硬盘后,在不关机的前提下扫 ...

  8. 关于react-router最新版本的使用

    现在react-router已经更新到了5.1.1版本,在一些使用方法上较之前有了很多改变,现做初步列举,以后会陆续更新. 关于引入react-router和基本使用 旧版本中引入react-rout ...

  9. 读《深入理解Elasticsearch》点滴-查询分类

    1.如何分类,略.个人不接受书中的分类方法,建议采用官网上的分类方法 2.term查询,可以模拟No-SQL数据库

  10. mybatis collection和association使用区别

    1. association-关联,用于一对一(如人与身份证)和多对一(如班级和学生) 2. collection-集合,用于一对多(如学生和班级)的关系