KMP 算法(Knuth–Morris–Pratt algorithm)的基本思想
KMP 算法(Knuth–Morris–Pratt algorithm)的基本思想
阅读本文之前,您最好能够了解 KMP 算法解决的是什么问题,最好能用暴力方式(Brute Force)解决一下该问题。
KMP 算法主要想解决的是文本搜索的问题: 给定一个模式字符串 p 和一个子串 t, 找出 p 串出现在 t 串中的位置。
术语定义
"abc"(引号中的字符串): 代表字符串字面值- a…z(单个斜体小写字母): 代表字符串。
- A…Z(单个大写字母):代表单个字符。
- prefix(x, n): 字符串 x 的前 n 个字符构成的子串(前缀)。
- suffix(x, n): 字符串 x 的后 n 个字符构成的子串(后缀)。
- |a|: 字符串 a 的长度。
如: 字符串
x =
"abcdef", 则 prefix(
x, 3) =
"abc", suffix(
x, 3) =
"def",|
x| = 6。
KMP 算法的基本思想
假设字符串 x = prefix(p, n),且存在 i > 0 使得字符串 y := prefix(x, i) := suffix(x, i),
则p, x 和 y 之间的关系如下图:
若 t 串匹配到 p 串的前缀x,并且在 x 串的下一个串匹配失败,如下图:
仔细观察上图可以发现,此次匹配失败后,我们不用按照暴力算法直接将 p 串移动一位,从头开始比较。
而是将 prefix(x, i) 移动到 suffix(x, i) 的位置,继续比较第 |y|+1 位。
这是因为此时已经匹配成功的 p 串和 x 串(即, prefix(t,n)) 相等。
结合下图(移动后的情况),仔细理解上一句话:
以上,就是 KMP 算法的最核心思想。我们不难发现,i 越大,移动之后匹配成功的字符就越多, 并且只有 i 取得最大值时, 才不会移动过多的位。
因此,KMP 算法找的是使得 prefix(p, i) == suffix(p, i) 最大的 i, 记作 i_max, 此时的 y 串记作 y _max。
容易求得,每次移动的位数是 |x| - | y _max|。
将 prefix(p, 1…|p|) (即 p 串的所有前缀 ) 的 i_max 打成一个表格,就是 KMP 算法所谓的 next 数组。
KMP 算法(Knuth–Morris–Pratt algorithm)的基本思想的更多相关文章
- 我所理解的 KMP(Knuth–Morris–Pratt) 算法
假设要在 haystack 中匹配 needle . 要理解 KMP 先需要理解两个概念 proper prefix 和 proper suffix,由于找到没有合适的翻译,暂时分别称真实前缀 和 真 ...
- 字符串匹配算法--KMP字符串搜索(Knuth–Morris–Pratt string-searching)C语言实现与讲解
一.前言 在计算机科学中,Knuth-Morris-Pratt字符串查找算法(简称为KMP算法)可在一个主文本字符串S内查找一个词W的出现位置.此算法通过运用对这个词在不匹配时本身就包含足够的信息 ...
- KMP 算法 & 字符串查找算法
KMP算法 Knuth–Morris–Pratt algorithm 克努斯-莫里斯-普拉特 算法 algorithm kmp_search: input: an array of character ...
- 彻底弄明白之数据结构中的KMP算法
如何加速朴素查找算法? KMP,当然还有其他算法,后续介绍. Knuth–Morris–Pratt string search algorithm Start at LHS of strin ...
- KMP算法解析(转自图灵社区)
KMP算法是一个很精妙的字符串算法,个人认为这个算法十分符合编程美学:十分简洁,而又极难理解.笔者算法学的很烂,所以接触到这个算法的时候也是一头雾水,去网上看各种帖子,发现写着各种KMP算法详解的转载 ...
- LeetCode刷题--基础知识篇--KMP算法
KMP算法 关于字符串匹配的算法,最知名的莫过于KMP算法了,尽管我们日常搬砖几乎不可能去亲手实现一个KMP算法,但作为一种算法学习的锻炼也是很好的,所以记录一下. KMP算法是根据三位作者(D.E. ...
- 字符串匹配算法(三)-KMP算法
今天我们来聊一下字符串匹配算法里最著名的算法-KMP算法,KMP算法的全称是 Knuth Morris Pratt 算法,是根据三位作者(D.E.Knuth,J.H.Morris 和 V.R.Prat ...
- KMP算法学习以及小结(好马不吃回头草系列)
首先请允许我对KMP算法的三位创始人Knuth,Morris,Pratt致敬,这三位优秀的算法科学家发明的这种匹配模式可以大大避免重复遍历的情况,从而使得字符串的匹配的速度更快,效率更高. 首先引入对 ...
- 字符串模式匹配之KMP算法图解与 next 数组原理和实现方案
之前说到,朴素的匹配,每趟比较,都要回溯主串的指针,费事.则 KMP 就是对朴素匹配的一种改进.正好复习一下. KMP 算法其改进思想在于: 每当一趟匹配过程中出现字符比较不相等时,不需要回溯主串的 ...
- KMP算法——从入门到懵逼到了解
本博文參考http://blog.csdn.net/v_july_v/article/details/7041827 关于其它字符串匹配算法见http://blog.csdn.net/WINCOL/a ...
随机推荐
- 线性时间选择(含平均情况O(n)和最坏情况O(n)算法)
前言 本篇文章我将介绍 期望为线性时间 的选择算法和 最坏情况为线性时间 的选择算法,即分别为 平均情况下时间复杂度为O(n) 和 最坏情况下时间复杂度为O(n) 的线性时间选择.以下包含了我自己的全 ...
- 解决win7连接蓝牙耳机播放设备找不到的问题
前言 这个问题其实就是蓝牙驱动问题, 而用第三方软件安装驱动,如驱动精灵安装蓝牙驱动,可能会不出现缺失驱动问题,但是一些功能会受到限制(win7系统与其蓝牙驱动不兼容). 解决办法 去 Inter官网 ...
- 重新认识下JVM级别的本地缓存框架Guava Cache(3)——探寻实现细节与核心机制
大家好,又见面了. 本文是笔者作为掘金技术社区签约作者的身份输出的缓存专栏系列内容,将会通过系列专题,讲清楚缓存的方方面面.如果感兴趣,欢迎关注以获取后续更新. 通过<重新认识下JVM级别的本地 ...
- vue3 + element plus 使用字节跳动图标
使用场景: 提一下vue2 用法>> 下面回到正题 vue3 用法 1 安装包: npm install @icon-park/vue-next --save 2 字节跳动图标库取图地 ...
- vue-router路由之路-极简教程
01.什么是前端路由? 前端路由的一个大背景就是当下流行的单页应用SPA,一些主流的前端框架,如vue.react.angular都属于SPA,那什么是SPA呢? 1.1.SPA SPA(single ...
- 【机器学习】李宏毅——Flow-based Generative Models
前文我介绍了部分关于生成学习的内容,可以参考我这篇博文点此 前面介绍的各个生成模型,都存在一定的问题: 对于PixelRNN这类模型来说,就是从左上角的像素开始一个个地进行生成,那么这个生成顺序是否合 ...
- 手写Pinia存储的数据持久化插件
Pinia和Vuex的通病 Pinia和vuex的通病就是,页面刷新会导致数据丢失 解决通病 一.新建store import { defineStore } from 'pinia' //单独存放S ...
- [常用工具] mermaid学习笔记
mermaid是一个基于Javascript的图表绘制工具,类似markdown用文本语法,用于描述文档图形(流程图. 时序图.甘特图),开发者可以通过一段mermaid文本来生成SVG或者PNG形式 ...
- C语言函数值传递问题
C语言函数间值传递问题 错误示例 #include <stdio.h> int * pop() { int a[3]; // 定义的局部变量a[3]在调用完之后自动释放其空间 int i ...
- 区块链特辑——solidity语言基础(三)
Solidity语法基础学习 五.映射类型: 映射型态 Mapping Type 映射钥匙Key → 真实资料 Value mapping(KeyType → ValueType) VariableN ...