当前位置: 首页 > ai >正文

KMP算法:如何通过 next 数组推导模式串该从哪里继续匹配

目录

一、next 数组的本质:模式串的 “记忆地图”

二、计算 next[j] 的核心逻辑(递推法)

情况 1:t[j] == t[k](k = next[j])

①j + 1 是啥?

② next[j + 1] = next[j] + 1 是啥意思?

③ 结合例子,一步一步看(下标从 1 开始)

1. 初始值:next[1] = 0

2. 计算 next[2](j = 1,算 j + 1 = 2)

3. 计算 next[3](j = 2,算 j + 1 = 3)

4. 计算 next[4](j = 3,算 j + 1 = 4)

5. 计算 next[5](j = 4,算 j + 1 = 5)

④ 总结规律

情况 2:t[j] != t[k](k = next[j])

四、next 数组如何指导 “从哪继续匹配”?

五、总结:next 数组的 “找位置” 逻辑


 

这里的数组下标从1开始 

一、next 数组的本质:模式串的 “记忆地图”

想象模式串是一条路,每个位置 j 是一个 “岔路口”。当在 j 位置匹配失败时,next[j] 会告诉你:“别慌,回到前面这个位置 k,从这里重新走,能复用之前的匹配成果!”

这个 k 是模式串中 j 之前的子串的 “最长相等前缀和后缀的长度”(专业说法是 “最长公共前后缀”)。

二、计算 next[j] 的核心逻辑(递推法)

已知 next[0...j],求 next[j+1],分两种情况:

情况 1:t[j] == t[k]k = next[j]
  • 类比:你在模式串的 j 位置,发现当前字符和 k 位置字符一样,说明 “前缀能续上”。
  • 结论next[j+1] = next[j] + 1(最长公共前后缀长度 +1)。
j + 1 是啥?

j 是模式串当前处理到的位置(下标从 1 开始),j + 1 就是下一个要计算 next 值的位置

比如:

  • 当你算完 next[1], next[2], ..., next[j],下一步要算 next[j + 1],看模式串第 j + 1 个字符失配时该回退到哪。
② next[j + 1] = next[j] + 1 是啥意思?

这是 next 数组递推的核心规律

如果 模式串第 j 个字符 和 模式串第 next[j] 个字符 相等,那么 next[j + 1] 就等于 next[j] + 1

换句话说:

因为 “j 位置的字符” 能和 “next[j] 位置的字符” 匹配,所以 “j + 1 位置” 的最长公共前后缀长度,就是 “j 位置的最长公共前后缀长度 + 1”。

③ 结合例子,一步一步看(下标从 1 开始)

假设模式串 T = "ababc"(字符下标 1~5 对应 a,b,a,b,c),手动推导 next 数组:

1. 初始值:next[1] = 0

模式串第一个字符(T[1] = 'a'),没有前缀,所以 next[1] = 0(特殊规则)。

2. 计算 next[2]j = 1,算 j + 1 = 2
  • j = 1next[j] = next[1] = 0
  • 比较 T[j]T[1] = 'a')和 T[next[j]]T[0] 不存在,所以 next[2] = 1(另一种特殊规则:若 next[j] = 0,则 next[j + 1] = 1)。
3. 计算 next[3]j = 2,算 j + 1 = 3
  • j = 2next[j] = next[2] = 1
  • 比较 T[j]T[2] = 'b')和 T[next[j]]T[1] = 'a')→ 'b' != 'a',所以不能直接用 next[j] + 1
  • 此时需要回溯 next[j] 到 next[1] = 0,再比较 T[2] 和 T[0](不存在),最终 next[3] = 1
4. 计算 next[4]j = 3,算 j + 1 = 4
  • j = 3next[j] = next[3] = 1
  • 比较 T[j]T[3] = 'a')和 T[next[j]]T[1] = 'a')→ 'a' == 'a'
  • 所以 next[j + 1] = next[j] + 1 → next[4] = 1 + 1 = 2
5. 计算 next[5]j = 4,算 j + 1 = 5
  • j = 4next[j] = next[4] = 2
  • 比较 T[j]T[4] = 'b')和 T[next[j]]T[2] = 'b')→ 'b' == 'b'
  • 所以 next[j + 1] = next[j] + 1 → next[5] = 2 + 1 = 3
④ 总结规律
  • j + 1 是下一个要计算 next 值的位置,代表模式串的 “当前处理位置 + 1”。
  • next[j + 1] = next[j] + 1 的条件是:模式串第 j 个字符 ≡ 模式串第 next[j] 个字符
  • 这一步的本质是:利用模式串自身的 “部分匹配”,让 next 数组 “继承” 匹配长度,避免重复计算。

简单说,j + 1 是递推的 “下一步位置”,next[j] + 1 是 “能复用匹配成果时的递推公式”—— 核心就是用已知的 next[j] 推导未知的 next[j + 1] ,让模式串自己 “记住” 该回退到哪。

情况 2:t[j] != t[k]k = next[j]
  • 类比:当前字符不匹配,说明 “这条路走不通,得回到 k 的‘记忆位置’重新找”。
  • 结论:让 k = next[k],重复比较,直到 k=0 或找到相等字符。

示例(模式串 t = "ababca"):

  • 假设 j=5(字符 a),k = next[5] = 2(已算出)。
  • 若 t[5] != t[2]a != b),则 k = next[2] = 0,再比较 t[5] 与 t[0](若相等则 next[6] = 0 + 1 = 1)。

四、next 数组如何指导 “从哪继续匹配”?

当模式串在 j 位置失配时:

  • 直接让 j = next[j],跳到模式串的 next[j] 位置,继续和主串当前 i 位置比较。

五、总结:next 数组的 “找位置” 逻辑

  1. 计算 next[j]:通过递推,利用 “最长公共前后缀” 找模式串自身的回溯位置。
  2. 使用 next[j]:失配时,模式串指针 j 跳到 next[j],主串指针 i 不回退,直接继续比较。
http://www.xdnf.cn/news/12132.html

相关文章:

  • Vue3解决“找不到模块@/components/xxx.vue或其相应的类型声明ts文件(2307)”
  • 华为云Flexus+DeepSeek征文| 华为云Flexus X实例单机部署Dify-LLM应用开发平台全流程指南
  • Vue ②-computed || watch || 指令
  • oracle数据恢复—oracle数据库执行truncate命令后的怎么恢复数据?
  • deepseek-r1-0528-qwen3-8b本地部署:Ollama老版本大升级至0.9.0
  • Three.js光与影代码分析及原理阐述
  • C++STL-sting类的模拟实现
  • nginx.conf配置详解:从(413 Request Entity Too Large)说起
  • Scrum基础知识以及Scrum和传统瀑布式开发的区别
  • 计算机磁盘旁黄色警示标志消除|BitLocker关闭方法
  • <论文>(微软)WINA:用于加速大语言模型推理的权重感知神经元激活
  • 众趣科技与我爱我家达成战略合作:AI空间计算技术赋能重塑房产服务新范式
  • 服务器安装软件失败或缺依赖怎么办?
  • 使用vue3+ts+input封装上传组件,上传文件显示文件图标
  • 【试卷篇】Spring面试试卷题
  • POP3、IMAP、SMTP:三大邮件协议核心差异与应用场景解析
  • IO流听不懂?如何快速上手
  • 解读《网络安全法》最新修订,把握网络安全新趋势
  • 理解电池的极化:极化内阻与欧姆内阻解析
  • 在NLP文本处理中,将字符映射到阿拉伯数字(构建词汇表vocab)的核心目的和意义
  • 网络原理3—TCP 2
  • 数据驱动的智驾十年 特斯拉、Momenta合流闯进Robotaxi卫冕之战
  • 使用 Docker Compose 安装 PostgreSQL 16
  • css实现文字颜色渐变
  • 直线导轨微型化技术难点在哪里?
  • python项目中,。 __all__ = [‘StorageConfig‘] 这个__all__ 代表什么含义
  • uboot移植之GPIO上电初始状态的调整
  • HarmonyOS-ArkUI 自定义弹窗
  • 企业im,为企业设计的私有化即时通讯工具
  • [蓝桥杯]修改数组