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. Hadoop学习笔记—20.网站日志分析项目案例

    1.1 项目来源 本次要实践的数据日志来源于国内某技术学习论坛,该论坛由某培训机构主办,汇聚了众多技术学习者,每天都有人发帖.回帖,如图1所示. 图1 项目来源网站-技术学习论坛 本次实践的目的就在于 ...

  2. Python机器学习笔记:卷积神经网络最终笔记

    这已经是我的第四篇博客学习卷积神经网络了.之前的文章分别是: 1,Keras深度学习之卷积神经网络(CNN),这是开始学习Keras,了解到CNN,其实不懂的还是有点多,当然第一次笔记主要是给自己心中 ...

  3. 松软科技课堂:SQL之NOTNULL约束

    SQL NOT NULL 约束 NOT NULL 约束强制列不接受 NULL 值. NOT NULL 约束强制字段始终包含值.这意味着,如果不向字段添加值,就无法插入新记录或者更新记录. 下面的 SQ ...

  4. [VB.NET Tips]为VB.NET正名

    前言 我于2005年毕业,正值全国上上下下如火如荼的开展企业信息化的时代,正是大规模软件开发的年代. 那时.NET 已经发布了2.0,但是仍是VB6,Delphi,PowerBuilder的天下,是E ...

  5. MyEclipse 中无法直接使用BaseEncoder问题

    首先 :点击项目---->build path--->configure Build Path 然后:java build path --->libraries--->JRE ...

  6. 配置Redis(远程访问及授权设置)

    配置Redis(远程访问及授权设置) 1.将redis.conf里面的bind 127.0.0.1这一行注释掉,添加自己服务器的IP 2. 还有,找到protected-mode这行, 将改为yes. ...

  7. Java入门学习笔记(全)

    JAVA https://zhuanlan.zhihu.com/p/21454718 引用部分实验楼代码,侵删 先通读文档 再亲自试标程 复习时自己再批注 1.a = b += c = -~d a = ...

  8. java几个常见的基础错误

    1.String 相等 稍微有点经验的程序员都会用equals比较而不是用 ==,但用equals就真的安全了吗,看下面的代码 user.getName().equals("xiaoming ...

  9. 列表 元祖 range

    1.列表 list 存放一些数据的容器 比如 衣柜 书包 作用:存储一些数据,数据量比较大 可以下标 可以切片 可以步长 和字符串的完全一样 lst = [1,2,3] print(lst) #[1, ...

  10. Mysql高手系列 - 第18篇:mysql流程控制语句详解(高手进阶)

    Mysql系列的目标是:通过这个系列从入门到全面掌握一个高级开发所需要的全部技能. 这是Mysql系列第18篇. 环境:mysql5.7.25,cmd命令中进行演示. 代码中被[]包含的表示可选,|符 ...