KMP算法细节详解(带动图理解)(1)

简介: 前言KMP算法是为了字符串匹配问题而被研究出来的,字符串匹配问题就是查看一个字符串A是否是字符串B的子串,如果是字串的话,在B的哪个位置?此算法代码简练,但理解起来非常困难,建议挑出一整块时间来专门学习,本文作者写的非常用心,还不了解KMP的小伙伴一定要静下心来慢慢细品,你一定会有所收获🍊一、字符串匹配问题如果遇到这种在一个字符串中寻找另一个字符串的子串这种问题,大多数人第一时间想到的肯定是通过暴力匹配算法来完成,也就是Brute-Force算法简称BF算法,时间复杂度为O(m*n),如果有上千行上万文本呢?,时间成本一定会很高,所以D.E.Knuth,J.H.Morris和V.R.

前言

KMP算法是为了字符串匹配问题而被研究出来的,字符串匹配问题就是查看一个字符串A是否是字符串B的子串,如果是字串的话,在B的哪个位置?此算法代码简练,但理解起来非常困难,建议挑出一整块时间来专门学习,本文作者写的非常用心,还不了解KMP的小伙伴一定要静下心来慢慢细品,你一定会有所收获🍊

一、字符串匹配问题

如果遇到这种在一个字符串中寻找另一个字符串的子串这种问题,大多数人第一时间想到的肯定是通过暴力匹配算法来完成,也就是Brute-Force算法简称BF算法,时间复杂度为O(m*n),如果有上千行上万文本呢?,时间成本一定会很高,所以D.E.Knuth,J.H.Morris和V.R.Pratt三位大神提出了KMP算法,KMP(Knuth-Morris-Pratt )算法也由他们三个的名字命名。

1.BF算法


108b434d6a9f4003a2caafc1c6fae787.gif

2.KMP算法

肉眼可见的差距

195748572bb448ea9226ef49ec04fe73.gif

二、next数组

next数组是KMP算法的精髓

KMP之所以会这样高效的查找字符串全都是next数组的功劳,也就是动图中字符串下面的数字,KMP算法会根据生成的next数组来移动,如果比对错误,将子串的首位直接移动到主串对比错误的位置,随后根据next数组提供的下标向左移动x格,图中下标为-1,所以向左移动-1格,就是向右移动一格

278738af2231494a842af7c6bf30dd48.gif

三、手写nex思想

注:上面图片的下标是按照nextVal生成的,next数组生成请看下面,nextVal是next的改进版,后面会讲到,我们先理解next数组生成原理

next数组的值计算的是从第n位开始前面字符串的最大公共前后缀的长度,不包括整个字符串本身,比如有这样一个字符串

c0cb0141debc4beb9b7c98e8edc135c3.png

从第一位向前看,没有字符,没法求,所有人为规定next[0]固定为-1(这里也有部分老师讲解第一位是0,其实思想都一样只不过是下标不一样而已,我们学的是思想不用在意这些),从第二位b向前看,也没有公共前后缀,next[2]为0,从第三位c向前看,也没有,next[3]为0,第四位a向前看,也没从第一位向前看,没有字符,没法求,所有人为规定next[0]固定为-1(这里也有部分老师讲解第一位是0,其实思想都一样只不过是下标不一样而已,我们学的是思想不用在意这些),从第二位b向前看,也没有公共前后缀,next[2]为0,从第三位c向前看,也没有,next[3]为0,第四位a向前看,也没

b716df7cb2584705b2d3e65d40f7f4bb.gif

四、机算next思想

比如一个字符串abcda,此时next数组的最大公共前后缀是1,那如果加个b呢,abcdab,此时最大公共前后缀是2,加个c呢,最大公共前后缀就变成3,经过大量数据观察,发现每次最大公共前后缀最多+1。

如果一个字符串abcdeffabcde,此时最大公共前后缀是3,如果在后面加一个g,这个字符串变成abcdffabcdg,最大公共前后缀直接就变成了0,也就是说每次最大公共前后缀可能直接减少到0。

如果增加一个字符的时候,发现新增加的字符与前缀后面的字母不相同了,就会进行减少,如下图所示,一次次进行查找,当前新的最大相同前后缀是什么,直到查找到位置。

3f047d7c3d8a4bfda7634e48c47d8c45.gif

这种方法未免有些麻烦,我们可以利用已有的条件进行优化,如果没有找到,直接找到其对应的next数组的值的字符串的下标,进行比对,如果成功,将找打他的next数组的值进行+1,就是next数组最新一位的值,如果找到最后,会找到字符串下标为0的位置,0位置的next数组值是-1,拿到-1的话数组会报错,这里写代码的时候不要忘记处理

512d1e8b028b4d08b2e786ad23773dfa.gif

为什么可以这么做呢?因为前面红框的前缀,等于后面红框的后缀,我们在此基础上向后进行对比一位即可判断出next数组最新一位的值。

f9ece5ff888a4e4293de87a6c99e0955.png
























相关文章
|
2月前
|
算法
第四章 KMP算法理论基础
第四章 KMP算法理论基础
22 0
|
2月前
|
算法
KMP算法
KMP算法
39 0
|
4月前
|
算法 C++
A : DS串应用–KMP算法
这篇文章提供了KMP算法的C++实现,包括计算模式串的next数组和在主串中查找模式串位置的函数,用于演示KMP算法的基本应用。
|
5月前
|
数据采集 算法 JavaScript
揭开JavaScript字符串搜索的秘密:indexOf、includes与KMP算法
JavaScript字符串搜索涵盖`indexOf`、`includes`及KMP算法。`indexOf`返回子字符串位置,`includes`检查是否包含子字符串。KMP是高效的搜索算法,尤其适合长模式匹配。示例展示了如何在数据采集(如网页爬虫)中使用这些方法,结合代理IP进行安全搜索。代码示例中,搜索百度新闻结果并检测是否含有特定字符串。学习这些技术能提升编程效率和性能。
140 1
揭开JavaScript字符串搜索的秘密:indexOf、includes与KMP算法
|
4月前
|
算法
KMP算法
KMP算法
37 0
|
5月前
|
存储 算法 Python
“解锁Python高级数据结构新姿势:图的表示与遍历,让你的算法思维跃升新高度
【7月更文挑战第13天】Python中的图数据结构用于表示复杂关系,通过节点和边连接。常见的表示方法是邻接矩阵(适合稠密图)和邻接表(适合稀疏图)。图遍历包括DFS(深度优先搜索)和BFS(广度优先搜索):DFS深入探索分支,BFS逐层访问邻居。掌握这些技巧对优化算法和解决实际问题至关重要。**
52 1
|
5月前
|
数据采集 存储 算法
「AIGC算法」图搜索算法详解
本文探讨了图搜索算法,包括遍历和最短路径搜索。DFS和BFS是遍历算法,前者使用栈深入搜索,后者用队列逐层遍历。Dijkstra、Bellman-Ford、A*、Floyd-Warshall和Johnson算法则解决最短路径问题。文中还给出了DFS的Python实现示例。这些算法在路径规划、网络分析等领域有重要应用。
149 0
|
5月前
|
算法 Java
KMP算法详解及其在字符串匹配中的应用
KMP算法详解及其在字符串匹配中的应用
|
18天前
|
算法
基于WOA算法的SVDD参数寻优matlab仿真
该程序利用鲸鱼优化算法(WOA)对支持向量数据描述(SVDD)模型的参数进行优化,以提高数据分类的准确性。通过MATLAB2022A实现,展示了不同信噪比(SNR)下模型的分类误差。WOA通过模拟鲸鱼捕食行为,动态调整SVDD参数,如惩罚因子C和核函数参数γ,以寻找最优参数组合,增强模型的鲁棒性和泛化能力。
|
4天前
|
供应链 算法 调度
排队算法的matlab仿真,带GUI界面
该程序使用MATLAB 2022A版本实现排队算法的仿真,并带有GUI界面。程序支持单队列单服务台、单队列多服务台和多队列多服务台三种排队方式。核心函数`func_mms2`通过模拟到达时间和服务时间,计算阻塞率和利用率。排队论研究系统中顾客和服务台的交互行为,广泛应用于通信网络、生产调度和服务行业等领域,旨在优化系统性能,减少等待时间,提高资源利用率。