首页 > 编程语言 >KMP算法(史上最清晰版本,每一步思路都仔细剖解)

KMP算法(史上最清晰版本,每一步思路都仔细剖解)

时间:2025-01-09 23:00:04浏览次数:3  
标签:子串 剖解 前缀 相同 后缀 pattern next 算法 KMP

用一个更形象和详细的示例来说明如何构造 next(又称部分匹配表、失配表)。假设我们的模式串是:

pattern = "aabaaac"

我们希望为这个模式串构造一个数组 next[],其中 next[i] 表示 [0…i] 这个子串中“前缀”与“后缀”能够匹配的最长长度。换句话说,next[i] 是“pattern[0…i] 的最长相同前后缀的长度”。

1. 初步理解前后缀

•	前缀:字符串开头到某个中间位置之间的部分(不包含最后一个字符)。
•	后缀:字符串末尾到某个中间位置之间的部分(不包含最前一个字符)。

对 pattern[0…i] 而言:
• 它的「前缀」是 pattern[0…x],x < i。
• 它的「后缀」是 pattern[y…i],y > 0。

举例:对于子串 “aab”,它的前缀可以是 “a”, “aa”;后缀可以是 “b”, “ab”。
如果有某个前缀与后缀完全一样且尽可能长,那么 next[i] 就是它的长度。

2. 步骤概览

1.	初始化:next[0] = 0,因为只有一个字符时,没有可比较的前后缀。
2.	逐一计算:从 i = 1 开始计算 next[i],直到 i = len(pattern) - 1。
3.	使用指针 j:表示已经匹配到的前缀末端位置。
•	初始 j = 0。
•	如果当前字符 pattern[i] 与 pattern[j] 相同,那么 j++,并令 next[i] = j。
•	如果不同,就要回退 j,再试图继续匹配,直到 j == 0 或者找到能匹配的位置。

3. 详细案例:pattern = “aabaaac”

让我们一步步计算各个 i 的 next[i] 值。

3.1 初始化
• next = [0, 0, 0, 0, 0, 0, 0] (与 pattern 长度相同)
• i = 0:子串 “a”,没有前后缀,next[0] = 0。

3.2 i = 1,子串 “aa”
• 当前子串:“aa” (索引 0…1)
• 比较 pattern[1] 与 pattern[j],初始 j = 0:
• pattern[1] = ‘a’, pattern[0] = ‘a’, 相同,则 j++ → j = 1
• 设置 next[1] = j = 1

此时

next = [0, 1, 0, 0, 0, 0, 0]

3.3 i = 2,子串 “aab”
• 当前子串:“aab” (索引 0…2)
• j 的当前值继承自上一次,是 j = 1。
• 比较 pattern[2] 与 pattern[j] = pattern[1]:
• pattern[2] = ‘b’, pattern[1] = ‘a’, 不相同。
• 此时要回退:j = next[j-1] = next[0] = 0.
• 退到 j = 0 后,再比较:pattern[2] 与 pattern[0]:
• ‘b’ != ‘a’, 仍不相同,且 j == 0 就没法再退了。
• 所以 next[2] = 0.

此时

next = [0, 1, 0, 0, 0, 0, 0]

3.4 i = 3,子串 “aaba”
• 当前子串:“aaba” (索引 0…3)
• 上次计算结束 j 已经是 0,所以从 j = 0 开始。
• 比较 pattern[3] 与 pattern[j] → pattern[3] = ‘a’, pattern[0] = ‘a’,相同:
• j++, j=1, next[3] = 1.

此时

next = [0, 1, 0, 1, 0, 0, 0]

标签:子串,剖解,前缀,相同,后缀,pattern,next,算法,KMP
From: https://blog.csdn.net/myprogramc/article/details/145005143

相关文章

  • python 代码实现了一个结合数据包络分析(DEA)和粒子群优化(PSO)算法的模型,主要用于寻找一
    importnumpyasnpimportpandasaspdimportpickleimportrefromscipy.optimizeimportminimizeimportrandomimportmatplotlib.pyplotaspltimportscipy.statsasstatsfromconcurrent.futuresimportThreadPoolExecutor#加载数据,添加文件存在性验证......
  • android逆向—头条新闻app的token算法
    某刷新闻赚钱token算法逆向分析1.前言因为学校被当作高考考点,所以有了几天假期,正好可以用来逆逆前几天找到的一个刷新闻赚钱app。2.工具:Xposed、Charles、反射大师、VMOSPro3.抓包:通过抓包,发现手机验证码提交时有一个token。4.逆向token算法在jadx-gui里直接搜索t......
  • 从上千份大厂面经呕心沥血整理:大厂高频手撕面试题(数据结构和算法篇 ,C++实现亲试可跑)
    目录 怎么判断两个链表是否相交?怎么优化?(字节跳动、货拉拉)手撕冒泡排序(美团)手撕快速排序(作业帮)手撕堆排序(美团)手撕归并排序(美团)手撕二分查找(VIVO)字符串的全排列(要求去重)(字节跳动)求一个字符串中最长不重复子串的长度(字节跳动) 反转字符串的单词:如何在原字符串上翻转......
  • 基于麻雀算法的Otsu图像多阈值分割(python)
    基于麻雀算法的Otsu图像多阈值分割(python)文章目录基于麻雀算法的Otsu图像多阈值分割(python)1.Otsu阈值分割法原理2.基于麻雀优化的多阈值分割3.算法结果:4.参考文献:5.Python代码:摘要:Otsu方法是应用最广泛的图像分割法之一,该方法也叫最大类间方法阈值分割法,选择分割阈......
  • 思维的进化:从链式推理到元链式推理的算法探秘
    ......
  • 关于字符检测的算法
    说到字符检测.,我们想到的首先就是提取字符,然后创建模版,利用定位仿射变换到新的字符上,做差值运算,得到的插值区域就是我们的异常区域.那么具体步骤怎么实现,halcon算子又该如何运用呢?①图像的预处理.a.一般选择自动阈值或绝对阈值.得到感兴趣区域.自动阈值算法,请......
  • memtest算法移植到uboot中---------下篇
    //memtest_boot.c#include"memtest_boot.h"//简单的随机数生成器staticulrand_seed=1;staticulsimple_rand(void){  rand_seed=rand_seed*1103515245+12345;  returnrand_seed;}//比较两块内存区域staticintcompare_regions(ulv*bufa,......
  • 遗传算法求解物流配送中心选址模型的MATLAB程序代码
    遗传算法求解物流配送中心选址模型的MATLAB程序代码列表GA/center.mat , 183GA/Consumer.mat , 234GA/costfun.m , 1437GA/dem.mat , 205GA/Distance.m , 171GA/DrawPath.m , 214GA/factory.mat , 183GA/Fitness.m , 69GA/GA.m , 2344GA/InitPop.m ......
  • 【雪花算法的实现原理】
    雪花算法的实现原理一、ID结构二、实现原理三、算法特点四、注意事项雪花算法(Snowflake)是由Twitter开源的一种分布式ID生成算法,其核心思想是将64位的long型ID分为四个部分,分别为:符号位、时间戳、工作机器ID、序列号。雪花算法的实现原理:一、ID结构符号位(1位......
  • 算法练习03
    一、题目给你两个字符串haystack和needle,请你在haystack字符串中找出needle字符串的第一个匹配项的下标(下标从0开始)。如果needle不是haystack的一部分,则返回-1。示例1:输入:haystack="sadbutsad",needle="sad"。输出:@解释:"sad”在下标0和6处匹配。第一个匹......