数据结构字符串匹配KMP算法的详解(题目讲解 简单易懂)

简介: 数据结构字符串匹配KMP算法的详解(题目讲解 简单易懂)

有问题欢迎评论区私信留言交流~~~

博主近来在复习数据结构的过程中遇到了KMP字符串匹配算法,在浏览了网上众多文章后感觉写的不够清晰和简单易懂,尤其是从做题的角度上来讲,下面就个人对KMP算法的理解进行解题,有问题还请谅解~

首先我们来看一下KMP算法的定义

KMP算法定义

KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)。KMP算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是通过一个next()函数实现,函数本身包含了模式串的局部匹配信息。KMP算法的时间复杂度O(m+n)

KMP算法是三位学者在 Brute-Force算法的基础上同时提出的模式匹配的改进算法。Brute- Force算法在模式串中有多个字符和主串中的若干个连续字符比较都相等,但最后一个字符比较不相等时,主串的比较位置需要回退。KMP算法在上述情况下,主串位置不需要回退,从而可以大大提高效率

所以我们可以明确KMP算法的核心就是当一位字符串匹配失败后子串应该移动的距离,所以关键是要求出这个移动的距离,明确了我们的目标之后下面我们以具体的题目进行讲解

基本概念

首先我们明确几个题目中要用到的基本概念

1:主串 就是要被匹配的串

2:字串 也称模式串,用于匹配主串

3:前缀

4:后缀

5:最长相等前后缀长度

6:部分匹配值PM

7:next数组

8:nextval数组

想必大家看到上面如此多的概念难免头晕犯难,下面我们以具体的题目进行讲解,这个算法实际上非常好理解

前缀指的是除最后一个字符外,字符串的所有头部字串。后缀指的是除第一个字符外,字符串的所有尾部子串,部分匹配值即为字符串的前缀和后缀的最长相等前后缀长度

下面我们从一个具体的例子来求解以上概念

按照规则一个个求前后缀即可,这里有一个小坑就是后缀是从往前的,所以是ba bab...

那么上面的部分匹配值表中某个字符不匹配时子串需要向后移动的位数计算公式如下

移动位数=已匹配的字符数-对应字符的部分匹配值

切记,此处查找的是最后一个匹配字符即下图b的部分匹配值

方法如下图所示,其余字符不匹配方法相同,直至字符串匹配成功或匹配失败为止

这里写错了 应该是b的部分匹配值为0

那么问题来了,既然上面已经可以计算出移动位数,那么next和nextval数组又是什么呢?

因为上面的计算方法还是不够直观和简单,还要查找上一个字符的部分匹配值,所以我们进一步简化,将PM表整体右移一位,就得到了next数组,第一个元素右移后空缺用-1填充,最后一个元素右移溢出不用理会直接舍去,有时为了计算方便也可以next数组值整体加1,这点应根据题目干条件灵活应对,其实串为序从1开始就整体+1,从0开始则不用加

此时移动位数=已匹配字符数-对应部分的next数组值(即不用看上一位的部分匹配值)

所以上图中的next数组为-1 0 0 01 如果加1则为 0 1 1 1 2读者可自行验证

最后nextval数组就是对KMP算法的进一步优化,失配时如果Pj=Pnext[j]则会匹配相等的字符,解决办法是递归计算next[j]并将更新后的next[j]命名为nextval[j],递归计算方法为

nextval[j]=next[next[j]]

如果递归一次后仍然相等则继续递归,直至不等即可

创作不易 觉得有帮助请点赞关注收藏~~~

相关文章
|
1月前
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
65 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
|
1月前
|
机器学习/深度学习 存储 缓存
数据结构与算法学习十:排序算法介绍、时间频度、时间复杂度、常用时间复杂度介绍
文章主要介绍了排序算法的分类、时间复杂度的概念和计算方法,以及常见的时间复杂度级别,并简单提及了空间复杂度。
23 1
数据结构与算法学习十:排序算法介绍、时间频度、时间复杂度、常用时间复杂度介绍
|
27天前
|
存储 算法 Java
Set接口及其主要实现类(如HashSet、TreeSet)如何通过特定数据结构和算法确保元素唯一性
Java Set因其“无重复”特性在集合框架中独树一帜。本文解析了Set接口及其主要实现类(如HashSet、TreeSet)如何通过特定数据结构和算法确保元素唯一性,并提供了最佳实践建议,包括选择合适的Set实现类和正确实现自定义对象的hashCode()与equals()方法。
31 4
|
1月前
|
搜索推荐 算法
数据结构与算法学习十四:常用排序算法总结和对比
关于常用排序算法的总结和对比,包括稳定性、内排序、外排序、时间复杂度和空间复杂度等术语的解释。
19 0
数据结构与算法学习十四:常用排序算法总结和对比
|
1月前
|
存储 缓存 分布式计算
数据结构与算法学习一:学习前的准备,数据结构的分类,数据结构与算法的关系,实际编程中遇到的问题,几个经典算法问题
这篇文章是关于数据结构与算法的学习指南,涵盖了数据结构的分类、数据结构与算法的关系、实际编程中遇到的问题以及几个经典的算法面试题。
29 0
数据结构与算法学习一:学习前的准备,数据结构的分类,数据结构与算法的关系,实际编程中遇到的问题,几个经典算法问题
|
1月前
|
机器学习/深度学习 搜索推荐 算法
探索数据结构:初入算法之经典排序算法
探索数据结构:初入算法之经典排序算法
|
1月前
|
存储 C语言
栈和队列题目练习
栈和队列题目练习
16 0
|
1月前
|
算法 Java 索引
数据结构与算法学习十五:常用查找算法介绍,线性排序、二分查找(折半查找)算法、差值查找算法、斐波那契(黄金分割法)查找算法
四种常用的查找算法:顺序查找、二分查找(折半查找)、插值查找和斐波那契查找,并提供了Java语言的实现代码和测试结果。
18 0
|
1月前
|
算法
第四章 KMP算法理论基础
第四章 KMP算法理论基础
18 0
|
1月前
|
存储 算法 Java
数据结构和算法--分段树
数据结构和算法--分段树
14 0