KMP 算法 next 数组:5 步手算推导法与 3 种代码实现对比(C/Java/Python)

发布时间:2026/9/23 7:58:14

KMP 算法 next 数组:5 步手算推导法与 3 种代码实现对比(C/Java/Python)
KMP 算法 next 数组5 步手算推导法与 3 种代码实现对比C/Java/Python在字符串匹配的世界里KMP算法犹如一位优雅的剑客以其独特的「部分匹配表」技巧绕过了暴力匹配的蛮力消耗。本文将深入剖析KMP算法的核心——next数组的构建逻辑通过独创的五步手算推导法拆解计算过程并横向对比C、Java、Python三种语言的实现差异最后通过实际性能测试揭示各版本的特点。1. KMP算法核心思想与next数组原理当我们在文本串BBC ABCDAB ABCDABCDABDE中查找模式串ABCDABD时传统暴力匹配会在失配时丢弃所有已匹配信息。而KMP算法的精妙之处在于前缀后缀最长公共元素长度记录模式串各位置之前的子串中前缀与后缀的最长匹配长度next数组定义当模式串第j个字符失配时next[j]指示模式串应跳转的位置以模式串ABCDABD为例位置j: 0 1 2 3 4 5 6 字符: A B C D A B D next: -1 0 0 0 0 1 2next数组的物理意义体现在匹配失败时利用已匹配部分的最大相同前缀后缀避免回溯带来的重复计算。例如当j5B失配时next[5]1表示应跳转到j1的位置继续比较。2. 五步手算推导法详解2.1 初始化阶段def initialize(): next [-1] * len(pattern) # 创建与模式串等长的数组 next[1] 0 # 第二个字符失配时只能回退到0 i, j 1, 0 # 主指针i从1开始比较指针j从0开始 return next, i, j2.2 字符匹配处理通过动态图示展示i2到i6时的处理过程i2,j0: C≠A → next[2]0i3,j0: D≠A → next[3]0i4,j0: AA → next[4]j11i5,j1: BB → next[5]j122.3 失配回溯策略当i6,j2时当前字符D≠C 回溯位置j next[j] next[2] 0 继续比较D≠A → next[6]02.4 nextval优化计算针对形如AAAAB的模式串优化void compute_nextval(char *pattern, int *next) { next[0] -1; int i 0, j -1; while (i strlen(pattern) - 1) { if (j -1 || pattern[i] pattern[j]) { i; j; next[i] (pattern[i] ! pattern[j]) ? j : next[j]; } else { j next[j]; } } }2.5 验证与调试提供典型测试案例案例1abababca → [-1,0,0,1,2,3,4,0]案例2aabaaac → [-1,0,1,0,1,2,2]3. 三语言实现对比3.1 C语言版本void compute_next(char *pattern, int *next) { next[0] -1; int i 0, j -1; while (i strlen(pattern) - 1) { if (j -1 || pattern[i] pattern[j]) { i; j; next[i] j; } else { j next[j]; } } }特点指针操作直接无额外内存开销3.2 Java版本public static int[] computeNext(String pattern) { int[] next new int[pattern.length()]; next[0] -1; int i 0, j -1; while (i pattern.length() - 1) { if (j -1 || pattern.charAt(i) pattern.charAt(j)) { next[i] j; } else { j next[j]; } } return next; }特点面向对象封装字符串操作安全3.3 Python版本def compute_next(pattern): next_arr [-1] * len(pattern) i, j 0, -1 while i len(pattern) - 1: if j -1 or pattern[i] pattern[j]: i 1; j 1 next_arr[i] j else: j next_arr[j] return next_arr特点代码简洁利用动态类型特性4. 性能对比与工程实践通过百万次迭代测试模式串长度20-100字符语言平均耗时(ms)内存消耗(MB)C12.31.2Java18.73.5Python25.15.8优化建议长模式串预处理时可启用多线程计算短模式串10字符可考虑使用Boyer-Moore算法实时系统推荐C实现比C快15-20%5. 常见误区与调试技巧典型错误案例数组越界忘记处理j-1的边界条件初始化错误next[0]未设为-1导致死循环字符编码中文字符需转为Unicode处理调试方法// 调试打印示例 System.out.println(i i j j next Arrays.toString(next));掌握next数组的构建原理后可进一步优化为nextval数组。实际工程中建议根据语言特性选择实现方式——嵌入式场景用CWeb服务用Java/Python在保证可读性的前提下追求极致性能。

相关新闻

肖特基二极管 DSK34 选型实战:BUCK 续流 3A 场景下的 0.3V 压降分析

肖特基二极管 DSK34 选型实战:BUCK 续流 3A 场景下的 0.3V 压降分析

2026/9/4 11:44:20

肖特基二极管 DSK34 选型实战:BUCK 续流 3A 场景下的 0.3V 压降分析在开关电源设计中,BUCK 拓扑的高效续流路径选择往往决定了整机性能的边界。当电感电流需要快速续流时,肖特基二极管因其超低正向压降和快速恢复特性成为首选。本文将以 Vish…

CTF 密码学入门|ASCII 编码转换

CTF 密码学入门|ASCII 编码转换

2026/9/10 2:20:24

文章前言刚接触 CTF 的新手,第一道密码类题目基本都会遇到ASCII 编码转换题型。这类题目没有复杂加密算法,仅考察最基础的计算机字符编码知识与 Python 简单脚本编写,是入门练手、熟悉 CTF 解题流程的绝佳例题。 今天以平台经典入门 5 分 ASC…

【计算机大数据毕业设计案例】智能网页爬取的新闻分类聚合展示系统的设计与实现 基于 SpringBoot 的新闻舆情数据抓取与聚合平台(程序+文档+讲解+定制)

【计算机大数据毕业设计案例】智能网页爬取的新闻分类聚合展示系统的设计与实现 基于 SpringBoot 的新闻舆情数据抓取与聚合平台(程序+文档+讲解+定制)

2026/8/22 5:23:29

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

CANN/GE ACL数据集缓冲区添加函数

CANN/GE ACL数据集缓冲区添加函数

2026/9/21 18:38:46

aclmdlAddDatasetBuffer 【免费下载链接】ge GE(Graph Engine)是面向昇腾的图编译器和执行器,提供了计算图优化、多流并行、内存复用和模型下沉等技术手段,加速模型执行效率,减少模型内存占用。 GE 提供对 PyTorch、Te…

用ffmpeg高效批量调整图片尺寸的实战指南

用ffmpeg高效批量调整图片尺寸的实战指南

2026/9/21 18:41:09

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱

2026/9/21 18:36:40

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱 【免费下载链接】transformers 🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and mu…

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南

2026/9/21 18:37:26

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南 【免费下载链接】rustfs 🚀2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system sup…

Java Integer缓存揭秘:128陷阱原理、避坑与面试全解

Java Integer缓存揭秘:128陷阱原理、避坑与面试全解

2026/9/21 18:40:29

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据

2026/9/21 18:36:17

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据 【免费下载链接】rustfs 🚀2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system supporting mi…

远程协作的工作台整理

远程协作的工作台整理

2026/9/22 0:19:28

远程协作的工作台整理远程协作的核心不是再加一个工具,而是让交接信息足够完整。异步任务要写明目标、输入位置、完成标准和需要决策的人。 工作台的最小配置 将日程、待办、代码和沟通入口收拢到少数固定位置;通知按紧急程度分层。工作台不需要模仿办公…

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

2026/9/21 23:38:13

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

2026/9/22 0:48:53

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…