七分钟理解什么是 KMP 算法
本文是介绍 什么是 BF算法、KMP算法、BM算法 三部曲之一。
KMP算法 内部涉及到的数学原理与知识太多,本文只会对 KMP算法 的运行过程、 部分匹配表 、next数组 进行介绍,如果理解了这三点再去阅读其它有关 KMP算法 的文章肯定能有个清晰的认识。
以下的文字描述请结合视频动画来阅读~
视频地址:https://www.bilibili.com/video/av60334201/
定义
Knuth-Morris-Pratt 字符串查找算法,简称为 KMP算法,常用于在一个文本串 S 内查找一个模式串 P 的出现位置。
这个算法由 Donald Knuth、Vaughan Pratt、James H. Morris 三人于 1977 年联合发表,故取这 3 人的姓氏命名此算法。
是不是感觉 Donald Knuth 这个名字很眼熟?没错,在前面 这或许是讲解 Knuth 洗牌算法最好的文章 一文中也出现了他!
下面直接给出 KMP算法 的操作流程:
- 假设现在文本串 S 匹配到 i 位置,模式串 P 匹配到 j 位置
- 如果 j = -1,或者当前字符匹配成功(即 S[i] == P[j] ),都令 i++,j++,继续匹配下一个字符;
如果 j != -1,且当前字符匹配失败(即 S[i] != P[j] ),则令 i 不变,j = next[j]。此举意味着失配时,模式串 P相对于文本串 S 向右移动了 j - next [j] 位 - 换言之,将模式串 P 失配位置的 next 数组的值对应的模式串 P 的索引位置移动到失配处
看不明白?直接看动画!
运行过程
以下图文本串 S 与模式串 P 为例:

首先,列出模式串 P 的所有子串:
| a | |||||||
|---|---|---|---|---|---|---|---|
| a | b | ||||||
| a | b | a | |||||
| a | b | a | a | ||||
| a | b | a | a | b | |||
| a | b | a | a | b | c | ||
| a | b | a | a | b | c | a | |
| a | b | a | a | b | c | a | c |
然后,求得每一个子串的所有前缀与后缀。
前缀 指除了最后一个字符以外,一个字符串的全部头部组合;后缀 指除了第一个字符以外,一个字符串的全部尾部组合。
以第五列为例进行演示。
前缀为
| a | |||
|---|---|---|---|
| a | b | ||
| a | b | a | |
| a | b | a |
后缀为
| b | |||
|---|---|---|---|
| a | b | ||
| a | A | b | |
| b | a | a | b |
因此,它的前缀后缀的公共元素的最大长度为 2。
求得原模式串 P 的子串对应的各个前缀后缀的公共元素的 最大长度表 下图。

根据最大长度表 去求 next 数组:next 数组相当于“最大长度值” 整体向右移动一位,然后初始值赋为-1。

好了,获取了 next 数组 后,KMP 算法 的操作就很清晰了。
将模式串 P 与文本串 S 的字母一个个进行匹配,当失配的时候,模式串向右移动。
怎么移动?

比如模式串的 b 与文本串的 c 失配了,找出失配处模式串的 next数组 里面对应的值,这里为 0,然后将索引为 0 的位置移动到失配处。

七分钟理解什么是 KMP 算法的更多相关文章
- 通过图片对比带给你不一样的KMP算法体验
KMP 算法,俗称“看毛片”算法,是字符串匹配中的很强大的一个算法,不过,对于初学者来说,要弄懂它确实不易. 笔者认为,KMP 算法之所以难懂,很大一部分原因是很多实现的方法在一些细节的差异.体现在几 ...
- 模式匹配KMP算法
关于KMP算法的原理网上有很详细的解释,我试着总结理解一下: KMP算法是什么 以这张图片为例子 匹配到j=5时失效了,BF算法里我们会使i=1,j=0,再看s的第i位开始能不能匹配,而KMP算法接下 ...
- 什么是KMP算法?KMP算法推导
花了大概3天时间,了解,理解,推理KMP算法,这里做一次总结!希望能给看到的人带来帮助!! 1.什么是KMP算法? 在主串Str中查找模式串Pattern的方法中,有一种方式叫KMP算法 KMP算法是 ...
- 问题 1690: 算法4-7:KMP算法中的模式串移动数组
题目链接:https://www.dotcpp.com/oj/problem1690.html 题目描述 字符串的子串定位称为模式匹配,模式匹配可以有多种方法.简单的算法可以使用两重嵌套循环,时间复杂 ...
- [转]KMP 算法
KMP 算法,俗称“看毛片”算法,是字符串匹配中的很强大的一个算法,不过,对于初学者来说,要弄懂它确实不易.整个寒假,因为家里没有网,为了理解这个算法,那可是花了九牛二虎之力!不过,现在我基本上对这个 ...
- <转>KMP算法详解
看了好久的KMP算法,都一直没有看明白,直到看到了这篇博客http://www.tuicool.com/articles/e2Qbyyf让我瞬间顿悟. 如果你看不懂 KMP 算法,那就看一看这篇文章 ...
- 浅谈KMP算法——Chemist
很久以前就学过KMP,不过一直没有深入理解只是背代码,今天总结一下KMP算法来加深印象. 一.KMP算法介绍 KMP解决的问题:给你两个字符串A和B(|A|=n,|B|=m,n>m),询问一个字 ...
- 串的应用与kmp算法讲解--学习笔记
串的应用与kmp算法讲解 1. 写作目的 平时学习总结的学习笔记,方便自己理解加深印象.同时希望可以帮到正在学习这方面知识的同学,可以相互学习.新手上路请多关照,如果问题还请不吝赐教. 2. 串的逻辑 ...
- 深入理解KMP算法
前言:本人最近在看<大话数据结构>字符串模式匹配算法的内容,但是看得很迷糊,这本书中这块的内容感觉基本是严蔚敏<数据结构>的一个翻版,此书中给出的代码实现确实非常精炼,但是个人 ...
随机推荐
- 继承Comparable接口来实现排序
1.java代码里进行排序(若sql能排序,就不要用代码排序) 可以继承Comparable接口来实现,若是在类中,可以声明Comparator对象,来进行比较 List<Map> map ...
- CLR 垃圾回收算法
c#相较于c,c++而言,在内存管理上为程序员提供了极大的方便,解放了程序员与内存地址打交道,提高了程序员的工作效率.比如c中分配的malloc堆空间没有释放导致的内存泄露,数组越界导致的踩内存错误, ...
- 数据结构与算法---查找算法(Search Algorithm)
查找算法介绍 在java中,我们常用的查找有四种: 顺序(线性)查找 二分查找/折半查找 插值查找 斐波那契查找 1)线性查找算法 示例: 有一个数列: {1,8, 10, 89, 1000, 123 ...
- 设计模式-工厂方法模式(FactoryMethod)
工厂方法模式又称多态工厂模式.工厂方法模式是定义一个创建产品对象的接口(FruitFactory),将具体创建工作给具体的实现类(AppFactory,BananaFactory,PearFactor ...
- Codeforces Gym101097I:Sticks (思维)
http://codeforces.com/gym/101097/attachments 题意:现在有k种颜色的木棍,每种颜色有ni根木棍,每根木棍有一个长度,问是否有三根木棍可以组成三角形,并且这三 ...
- Django中使用JS通过DataTable实现表格前端分页,每页显示页数,搜索等功能
Django架构中自带了后端分页的技术,通过Paginator进行分页,前端点击按钮提交后台进行页面切换. 优缺点:后端分页对于数据量大的场景有其优势,但页面切换比较慢. 后端分页python3代码如 ...
- 3.秋招复习简单整理之List、Map、Set三个接口存取元素时,各有什么特点?
List.Set都是单列元素的集合,它们有共同的父接口Collection. List存取有序可重复元素 存元素:调用add方法,存的元素先来后到,有顺序,当然也可以插队,指定存在某个位置,调用add ...
- Spring Cloud Alibaba | Nacos配置管理
目录 Spring Cloud Alibaba | Nacos配置管理 1. pom.xml 项目依赖 2. 在 bootstrap.properties 中配置 Nacos server 的地址和应 ...
- 浅谈 Attention 机制的理解
什么是注意力机制? 注意力机制模仿了生物观察行为的内部过程,即一种将内部经验和外部感觉对齐从而增加部分区域的观察精细度的机制.例如人的视觉在处理一张图片时,会通过快速扫描全局图像,获得需要重点关注的目 ...
- 零基础ASP.NET Core WebAPI团队协作开发
零基础ASP.NET Core WebAPI团队协作开发 相信大家对“前后端分离”和“微服务”这两个词应该是耳熟能详了.网上也有很多介绍这方面的文章,写的都很好.我这里提这个是因为接下来我要分享的内容 ...