KMP算法最浅显理解(小白教程)

KMP算法最浅显理解(小白教程)

什么是KMP算法?

KMP算法(Knuth-Morris-Pratt算法)是一种字符串匹配算法,用于在一个主串中查找一个模式串的出现位置。与朴素的字符串匹配算法相比,KMP算法具有更高的效率。

KMP算法的基本思想

KMP算法的基本思想是利用已经匹配过的部分信息,避免不必要的回溯。它通过构建一个部分匹配表(Partial Match Table),来记录模式串中的前缀和后缀的最长公共部分长度,从而在匹配过程中跳过一些不可能匹配的位置。

构建部分匹配表

部分匹配表是KMP算法的核心,它记录了模式串中每个位置的最长公共前缀后缀长度。下面是构建部分匹配表的步骤:

  1. 初始化部分匹配表,长度与模式串相同,初始值都为0。
  2. 从模式串的第二个字符开始,依次计算每个位置的最长公共前缀后缀长度。
  3. 对于每个位置i,假设前缀为P[0:i-1],后缀为P[1:i],计算它们的最长公共部分长度。
  4. 如果P[0:i-1]的最长公共部分长度为k,且P[i-1]等于P[k],则P[0:i]的最长公共部分长度为k+1。
  5. 如果P[0:i-1]的最长公共部分长度为k,且P[i-1]不等于P[k],则需要继续向前寻找更短的公共前缀后缀。
    • 如果P[0:k-1]的最长公共部分长度为m,且P[i-1]等于P[m],则P[0:i]的最长公共部分长度为m+1。
    • 如果P[0:k-1]的最长公共部分长度为m,且P[i-1]不等于P[m],则继续向前寻找更短的公共前缀后缀,直到找到长度为0的公共前缀后缀。
  6. 重复步骤3,直到计算完所有位置的最长公共前缀后缀长度。

KMP算法的匹配过程

KMP算法的匹配过程如下:

  1. 初始化主串的位置i为0,模式串的位置j为0。
  2. 逐个比较主串和模式串的字符:
  3. 如果主串的字符和模式串的字符相等,则继续比较下一个字符。
  4. 如果主串的字符和模式串的字符不相等:
    • 如果j等于0,表示模式串的第一个字符就不匹配,将i加1。
    • 如果j大于0,表示已经匹配了j个字符,但第j+1个字符不匹配,根据部分匹配表,将j更新为部分匹配表中j位置的值,继续比较主串的字符和模式串的字符。
  5. 如果模式串的位置j等于模式串的长度,表示匹配成功,返回主串中匹配的起始位置。
  6. 如果主串的位置i等于主串的长度,表示匹配失败,返回-1。

示例说明

示例1

主串:\"ABABABABCABABABABD\"
模式串:\"ABABABD\"

构建部分匹配表:

位置 字符 部分匹配值
0 A 0
1 B 0
2 A 1
3 B 2
4 A 3
5 B 4
6 D 0

匹配过程:

  • 第一步:i=0, j=0,A和A匹配。
  • 第二步:i=1, j=1,B和B匹配。
  • 第三步:i=2, j=2,A和A匹配。
  • 第四步:i=3, j=3,B和B匹配。
  • 第五步:i=4, j=4,A和A匹配。
  • 第六步:i=5, j=5,B和B匹配。
  • 第七步:i=6, j=6,D和D匹配。
  • 匹配成功,返回主串中匹配的起始位置为3。

示例2

主串:\"ABCABABABD\"
模式串:\"ABABABD\"

构建部分匹配表:

位置 字符 部分匹配值
0 A 0
1 B 0
2 A 1
3 B 2
4 A 3
5 B 4
6 D 0

匹配过程:

  • 第一步:i=0, j=0,A和A匹配。
  • 第二步:i=1, j=1,B和B匹配。
  • 第三步:i=2, j=2,C和A不匹配,根据部分匹配表,j更新为2。
  • 第四步:i=2, j=2,C和A不匹配,根据部分匹配表,j更新为1。
  • 第五步:i=2, j=1,C和B不匹配,根据部分匹配表,j更新为0。
  • 第六步:i=2, j=0,C和A不匹配,将i加1。
  • 第七步:i=3, j=0,A和A匹配。
  • 第八步:i=4, j=1,B和B匹配。
  • 第九步:i=5, j=2,A和A匹配。
  • 第十步:i=6, j=3,B和B匹配。
  • 第十一步:i=7, j=4,A和A匹配。
  • 第十二步:i=8, j=5,B和B匹配。
  • 第十三步:i=9, j=6,A和D不匹配,根据部分匹配表,j更新为0。
  • 第十四步:i=9, j=0,A和A匹配。
  • 第十五步:i=10, j=1,B和B匹配。
  • 第十六步:i=11, j=2,A和A匹配。
  • 第十七步:i=12, j=3,B和B匹配。
  • 第十八步:i=13, j=4,A和A匹配。
  • 第十九步:i=14, j=5,B和B匹配。
  • 第二十步:i=15, j=6,A和D不匹配,根据部分匹配表,j更新为0。
  • 第二十一步:i=15, j=0,A和A匹配。
  • 第二十二步:i=16, j=1,B和B匹配。
  • 第二十三步:i=17, j=2,A和A匹配。
  • 第二十四步:i=18, j=3,B和B匹配。
  • 第二十五步:i=19, j=4,A和A匹配。
  • 第二十六步:i=20, j=5,B和B匹配。
  • 第二十七步:i=21, j=6,A和D不匹配,根据部分匹配表,j更新为0。
  • 匹配失败,返回-1。

以上就是KMP算法的最浅显理解,希望对你有帮助!

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:KMP算法最浅显理解(小白教程) - Python技术站

(0)
上一篇 2023年8月6日
下一篇 2023年8月6日

相关文章

  • vue cli3 实现分环境打包的步骤

    实现分环境打包的步骤大致如下: 在项目根目录下创建 .env.development,.env.production,.env.test 等环境变量配置文件,分别对应开发环境、生产环境、测试环境等。其中,.env 文件是默认的主配置文件,所有环境的公共的变量都可以写在这个文件中,具体变量值可以在其他环境文件中覆盖。 示例1:在 .env 文件中设置公共变量,…

    other 2023年6月27日
    00
  • 怎么查看隐藏文件

    查看隐藏文件需要在操作系统中设置,下面是Windows和macOS两种操作系统的查看隐藏文件的具体方法: Windows 在Windows系统中,可以通过下面的步骤来查看隐藏文件: 打开”文件夹选项”对话框。按下Win + E打开文件资源管理器,然后在菜单栏中点击”查看”,在下拉菜单中选择”选项”。 在”文件夹选项”对话框中选择”查看”标签页,向下滚动找到”…

    其他 2023年4月16日
    00
  • MyBatisPlus使用@TableField注解处理默认填充时间的问题

    以下是关于MyBatis Plus使用@TableField注解处理默认填充时间的完整攻略,包含两个示例说明: 1. 使用@TableField注解设置默认填充时间字段 在实体类中,使用@TableField注解标注需要设置默认填充时间的字段,并设置fill属性为FieldFill.DEFAULT,如下所示: public class User { @Tab…

    other 2023年10月19日
    00
  • Spring Boot静态资源路径的配置与修改详解

    下面是Spring Boot静态资源路径的配置与修改详解。 为什么需要配置静态资源路径 在一个Web应用中,一般都包含了静态资源,如图片、CSS、JavaScript等。这些静态资源的访问路径是相对固定的,因此需要配置静态资源路径,让Spring Boot在处理静态资源时能够正确地找到它们。 Spring Boot默认的静态资源路径 Spring Boot默…

    other 2023年6月25日
    00
  • Linux中搭建完整的samba服务器全攻略(centos版)

    以下是详细讲解“Linux中搭建完整的samba服务器全攻略(centos版)”的完整攻略: 1. 安装samba 在CentOS中安装samba十分简单,可以通过以下命令完成安装: sudo yum install samba samba-client 2. 配置samba 2.1 创建sambashare目录,并设置共享权限: sudo mkdir /s…

    other 2023年6月27日
    00
  • win10系统32位怎么升64位系统?win10系统32位升64位系统操作教程

    升级操作系统的过程是比较复杂的,需要一定的技术知识和操作经验。在升级前,请务必备份重要的文件和数据,以防数据丢失。以下是升级Win10 32位系统到64位系统的详细攻略: 步骤1:检查硬件兼容性首先,你需要确认你的计算机硬件是否支持64位操作系统。打开计算机的控制面板,点击“系统和安全”,然后点击“系统”。在“系统类型”一栏中,如果显示的是“32位操作系统”…

    other 2023年7月28日
    00
  • resttemplate设置重试

    RestTemplate设置重试 在访问微服务时,经常会遇到网络波动或者服务不稳定的情况,可能导致请求失败或者超时。为了提高服务的可靠性,我们可以使用RestTemplate来进行重试机制的设置。 RestTemplate是什么 RestTemplate是Spring框架中的一个HTTP客户端工具,主要用于与RESTful服务进行交互。它封装了HTTP协议的…

    其他 2023年3月28日
    00
  • React Hook Form 优雅处理表单使用指南

    React Hook Form 优雅处理表单使用指南 React Hook Form 是一个用于处理表单的库,它提供了一种优雅的方式来处理表单验证和表单状态管理。本攻略将详细介绍如何使用 React Hook Form。 安装 首先,我们需要安装 React Hook Form。可以使用 npm 或者 yarn 进行安装: npm install react…

    other 2023年7月28日
    00
合作推广
合作推广
分享本页
返回顶部