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

【数据结构与算法】KMP算法(next数组)

#include iostream #include string #include vector using namespace std; int main() { string s1, s2; cin s1 s2; int n s1.size(); int m s2.size(); // Step 1: 构建 next 数组 (border 长度数组) vectorint next(m, 0); for (int i 1; i m; i) { int j next[i - 1]; while (j 0 s2[i] ! s2[j]) { j next[j - 1]; } if (s2[i] s2[j]) { j; } next[i] j; } // Step 2: KMP 匹配记录位置 vectorint positions; int j 0; for (int i 0; i n; i) { while (j 0 s1[i] ! s2[j]) { j next[j - 1]; } if (s1[i] s2[j]) { j; } if (j m) { // 匹配成功位置是 i - m 1 (0-based) positions.push_back(i - m 2); // 转为 1-based j next[j - 1]; } } // Step 3: 输出匹配位置 for (int i 0; i positions.size(); i) { cout positions[i] \n; } // Step 4: 输出 border 长度 (即 next 数组) for (int i 0; i m; i) { cout next[i]; if (i m - 1) cout ; } return 0; }KMP算法入门到实战从原理到洛谷P3375完整解析字符串匹配是数据结构与算法中非常经典的一类问题。最朴素的方法是暴力匹配但在数据规模较大的情况下效率很低而KMP算法正是为了解决这一问题而提出的。这篇文章结合洛谷 P3375 这道模板题从原理到代码完整讲清楚 KMP 到底在干什么以及为什么它能做到高效匹配。问题背景字符串匹配到底在做什么给定两个字符串主串 s1模式串 s2我们需要找到s2 在 s1 中所有出现的位置。例如s1 ABABABC s2 ABA答案是1 3也就是 s2 在 s1 中出现了两次。暴力匹配的问题为什么需要KMP最直接的想法是从 s1 的每个位置开始一个字符一个字符去比但问题在于一旦匹配失败我们就会“回退很多无意义的比较”例如ABABABC ABA匹配到一半失败又要从头开始很多字符被重复比较。KMP 的核心思想就是不回退主串利用已经匹配的信息直接跳到合理的位置继续匹配KMP核心next数组border思想KMP最关键的就是next数组也叫前缀函数。它的含义是next[i] 表示子串 s2[0...i] 的最长“前缀 后缀”的长度这里的“前缀”和“后缀”前缀从开头开始的子串后缀从结尾开始的子串但不能是整个字符串本身例如s2 ABA计算过程A → 0AB → 0ABA → 1前缀A 后缀A所以next [0, 0, 1]为什么next数组这么重要当匹配失败时我们可以利用 next 数组把模式串往右“滑动”但不是重新开始而是跳到一个已经匹配过的位置本质上就是已经匹配成功的一部分不需要重新匹配直接复用这就是 KMP 能做到 O(n m) 的原因。代码解析一步一步看懂实现next数组构建过程别只背模板这一段是很多人卡住的地方for (int i 1; i m; i) { int j next[i - 1]; while (j 0 s2[i] ! s2[j]) { j next[j - 1]; } if (s2[i] s2[j]) { j; } next[i] j; }可以这样理解j 表示“当前能匹配的前缀长度”如果失配就往更短的 border 跳直到找到可以继续匹配的位置本质是在“历史信息”中找一个还能继续匹配的位置匹配过程真正体现KMP价值的地方这一段逻辑和 next 构建几乎一样while (j 0 s1[i] ! s2[j]) { j next[j - 1]; }含义是如果当前字符不匹配就利用 next 数组“跳回去”而不是从头开始当j m时说明完整匹配了一次记录位置然后继续匹配支持重叠本题额外要求border长度输出题目不仅要求匹配位置还要求输出 s2 每个前缀的最长 border 长度其实就是next 数组本身所以直接输出即可。一个容易忽略的细节这一句positions.push_back(i - m 2);很多人会写错。原因是i 是当前匹配结束位置0-based起点 i - m 1再转成 1-based → 1所以是i - m 2总结KMP其实可以用一句话概括利用“已经匹配过的信息”避免重复比较核心只有两个next数组记录可复用信息匹配时不回退主串理解了这一点代码只是形式。最后一点建议如果你觉得KMP难大概率不是代码问题而是没真正理解“next数组在表示什么”建议你自己拿一个字符串比如ABABAC手动推一遍 next 数组你会突然明白很多。一旦这一步通了KMP基本就彻底掌握了。

相关文章:

【数据结构与算法】KMP算法(next数组)

#include <iostream> #include <string> #include <vector> using namespace std; int main() {string s1, s2;cin >> s1 >> s2;int n s1.size();int m s2.size();// Step 1: 构建 next 数组 (border 长度数组)vector<int> next(m, 0);f…...

手把手教你用ECharts-wordcloud实现炫酷文字云图(附完整配置代码)

手把手教你用ECharts-wordcloud实现炫酷文字云图&#xff08;附完整配置代码&#xff09; 文字云图&#xff08;Word Cloud&#xff09;作为一种直观的数据可视化形式&#xff0c;能够通过字体大小和颜色变化突出关键词的重要性&#xff0c;广泛应用于舆情分析、用户画像和内容…...

RexUniNLU零样本实战:从电商评论到合同审核,一键搞定多领域信息抽取

RexUniNLU零样本实战&#xff1a;从电商评论到合同审核&#xff0c;一键搞定多领域信息抽取 1. 引言&#xff1a;零样本信息抽取的革命性突破 1.1 传统NLP落地的三大痛点 在自然语言处理领域&#xff0c;信息抽取一直是个"高门槛"任务。传统方案通常面临以下挑战&…...

Playwright vs Selenium:Python自动化测试工具对比与实战演示

Playwright vs Selenium&#xff1a;Python自动化测试工具深度评测与选型指南 在当今快速迭代的软件开发周期中&#xff0c;自动化测试已成为保障产品质量不可或缺的一环。Python作为自动化测试领域的主流语言&#xff0c;其丰富的测试框架生态让开发者面临甜蜜的烦恼——如何在…...

SOONet多场景落地:司法审讯录像关键陈述定位、医疗手术步骤索引

SOONet多场景落地&#xff1a;司法审讯录像关键陈述定位、医疗手术步骤索引 1. 项目概述 SOONet是一个基于自然语言输入的长视频时序片段定位系统&#xff0c;它能够通过一次网络前向计算就精确定位视频中的相关片段。这个技术解决了传统视频分析中需要逐帧查看或依赖复杂算法…...

AI大模型进阶指南:从入门到实战,这份89份资料包助你成为行业精英!AI大模型学习和八股文资料合集

随着人工智能技术的飞速发展&#xff0c;AI大模型&#xff08;如GPT、LLaMA、ChatGLM&#xff09;已成为推动行业变革的核心力量。无论是开发者、研究者&#xff0c;还是产品经理&#xff0c;掌握大模型的核心技术与应用方法都至关重要。然而&#xff0c;面对海量学习资源&…...

php方案 序数据库: PHP 如何利用 pack 和 unpack 函数实现高效的压缩存储时序数据?

核心思路时序数据两个特点可以利用&#xff1a;- 时间戳是递增的&#xff0c;存差值比存完整时间戳省空间- 文本存 1710000000 是10字节&#xff0c;二进制存只要4字节---代码// 编码&#xff1a;数组 → 二进制function ts_pack(array $data): string {$base array_key_first…...

HP-Socket技术文档错误反馈机制:收集与修复流程

HP-Socket技术文档错误反馈机制&#xff1a;收集与修复流程 【免费下载链接】HP-Socket High Performance TCP/UDP/HTTP Communication Component 项目地址: https://gitcode.com/gh_mirrors/hp/HP-Socket HP-Socket作为高性能TCP/UDP/HTTP通信组件&#xff0c;其技术文…...

OpenCASCADE法向获取避坑指南:为什么你的法线方向总是反的?

OpenCASCADE法向获取避坑指南&#xff1a;为什么你的法线方向总是反的&#xff1f; 在三维建模和CAD开发中&#xff0c;法线方向是一个看似简单却经常让开发者头疼的问题。特别是对于OpenCASCADE这样的开源几何建模内核&#xff0c;初学者经常会遇到明明按照文档操作&#xff0…...

STM32温室环境闭环控制系统设计与实现

1. 项目概述1.1 系统定位与工程目标本项目为面向实际农业场景的嵌入式温室环境闭环控制系统&#xff0c;核心目标是构建一套具备本地实时监控、多维度环境感知、分级执行控制及远程人机交互能力的软硬件协同平台。系统并非概念验证原型&#xff0c;而是以可部署性为设计前提&am…...

MKBSD vs Panels:哪款才是壁纸爱好者的真正选择?

MKBSD vs Panels&#xff1a;哪款才是壁纸爱好者的真正选择&#xff1f; 【免费下载链接】mkbsd Download all the wallpapers in MKBHDs "Panels" app 项目地址: https://gitcode.com/gh_mirrors/mk/mkbsd 在数字时代&#xff0c;壁纸不仅是设备的装饰&#…...

Pixel Dimension Fissioner开箱即用:内置10个行业模板(教育/电商/游戏/政务等)

Pixel Dimension Fissioner开箱即用&#xff1a;内置10个行业模板&#xff08;教育/电商/游戏/政务等&#xff09; 1. 产品概述 Pixel Dimension Fissioner&#xff08;像素语言维度裂变器&#xff09;是一款基于MT5-Zero-Shot-Augment核心引擎构建的创新型文本增强工具。它将…...

SWF逆向工程道德准则:JPEXS Free Flash Decompiler使用规范

SWF逆向工程道德准则&#xff1a;JPEXS Free Flash Decompiler使用规范 【免费下载链接】jpexs-decompiler JPEXS Free Flash Decompiler 项目地址: https://gitcode.com/gh_mirrors/jp/jpexs-decompiler JPEXS Free Flash Decompiler是一款功能强大的SWF逆向工程工具&a…...

逆向实战:如何用Unidbg+DFA破解某App的白盒AES加密(附完整代码)

逆向工程实战&#xff1a;Unidbg与DFA技术破解白盒AES加密全解析 在移动应用安全研究领域&#xff0c;白盒加密技术因其特殊的保护机制成为逆向分析中的难点。本文将深入探讨如何结合Unidbg模拟执行框架与差分故障分析&#xff08;DFA&#xff09;技术&#xff0c;实现对某移动…...

乡村采摘园财务管理流程 Coze 工作流开发文档

乡村采摘园财务管理流程 Coze 工作流开发文档 1. 项目背景与目标 随着乡村旅游的兴起,乡村采摘园作为一种集农业、旅游、休闲于一体的新型业态,其财务管理变得日益重要。传统的手工记账方式效率低下、易出错,且难以进行多维度的数据分析与可视化呈现。本项目的目标是利用 …...

在嵌入式AI边缘端集成mediamtx:构建轻量级RTSP流媒体服务

1. 为什么选择mediamtx作为嵌入式AI边缘端的流媒体解决方案 在嵌入式AI应用中&#xff0c;处理完的视频流往往需要实时发布给其他设备或系统。传统方案通常需要部署NginxRTMP模块&#xff0c;但这种组合对资源有限的嵌入式设备来说显得过于臃肿。mediamtx这个开源的流媒体服务器…...

TeslaMate低功耗优化终极指南:树莓派部署的节能设置与性能平衡

TeslaMate低功耗优化终极指南&#xff1a;树莓派部署的节能设置与性能平衡 【免费下载链接】teslamate 项目地址: https://gitcode.com/gh_mirrors/tes/teslamate TeslaMate是一款强大的开源Tesla车辆数据监控工具&#xff0c;通过树莓派部署可实现24/7不间断数据采集。…...

Qwen3-TTS-12Hz-1.7B-VoiceDesign 语音密码:声纹生物特征认证

Qwen3-TTS-12Hz-1.7B-VoiceDesign 语音密码&#xff1a;声纹生物特征认证 1. 引言 想象一下这样的场景&#xff1a;你正在银行APP上进行一笔重要转账&#xff0c;系统不再要求你输入繁琐的密码或验证码&#xff0c;而是让你说一句"今天天气不错"&#xff0c;系统通…...

WinPwn代码架构深度解析:理解5200行PowerShell脚本的设计原理

WinPwn代码架构深度解析&#xff1a;理解5200行PowerShell脚本的设计原理 【免费下载链接】WinPwn Automation for internal Windows Penetrationtest / AD-Security 项目地址: https://gitcode.com/gh_mirrors/wi/WinPwn WinPwn是一款专为Windows渗透测试和AD安全审计设…...

告别卡顿!给香橙派PC刷上Ubuntu 22.04,保姆级烧录与开机配置指南

告别卡顿&#xff01;给香橙派PC刷上Ubuntu 22.04&#xff0c;保姆级烧录与开机配置指南 香橙派PC作为一款高性价比的单板计算机&#xff0c;凭借其全志H3四核处理器和1GB内存的配置&#xff0c;在开发者社区中广受欢迎。然而&#xff0c;许多用户在初次使用时常常遇到系统卡顿…...

C#面试必问:垃圾回收(GC)机制详解与实战避坑指南

C#面试必问&#xff1a;垃圾回收(GC)机制详解与实战避坑指南 在准备C#技术面试时&#xff0c;垃圾回收机制(GC)几乎是必问的核心知识点。但很多开发者对GC的理解仅停留在"自动内存管理"的层面&#xff0c;当面试官深入追问分代回收原理或性能优化时&#xff0c;往往难…...

对比一圈后 9个降AIGC平台深度测评,全行业通用必看

在当前学术和商业写作环境中&#xff0c;AI生成内容&#xff08;AIGC&#xff09;的普及让论文查重率问题变得尤为突出。无论是学生、研究人员还是企业文案撰写者&#xff0c;都面临着一个共同挑战&#xff1a;如何在保持原文逻辑与语义不变的前提下&#xff0c;有效降低AI痕迹…...

EasyImages2.0第三方工具集成指南:PicGo、ShareX、uPic深度整合

EasyImages2.0第三方工具集成指南&#xff1a;PicGo、ShareX、uPic深度整合 【免费下载链接】EasyImages2.0 简单图床 - 一款功能强大无数据库的图床 2.0版 项目地址: https://gitcode.com/gh_mirrors/ea/EasyImages2.0 想要将EasyImages2.0简单图床的强大功能无缝集成到…...

LCD显示开发常见问题:当两个.c文件包含同一个数组定义时(L6200E错误全解析)

LCD显示开发中的重复定义陷阱&#xff1a;L6200E错误深度解析与最佳实践 1. 从现象到本质&#xff1a;理解L6200E错误的根源 在嵌入式LCD显示开发中&#xff0c;当工程规模逐渐扩大&#xff0c;模块化程度提高时&#xff0c;开发者常会遇到一个令人困惑的链接错误&#xff1a;L…...

SWF文件恢复成功率统计:JPEXS Free Flash Decompiler案例数据

SWF文件恢复成功率统计&#xff1a;JPEXS Free Flash Decompiler案例数据 【免费下载链接】jpexs-decompiler JPEXS Free Flash Decompiler 项目地址: https://gitcode.com/gh_mirrors/jp/jpexs-decompiler JPEXS Free Flash Decompiler是一款功能强大的开源SWF文件恢复…...

流形学习避坑指南:为什么你的t-SNE可视化效果总不好?

流形学习实战解析&#xff1a;从算法原理到可视化效果优化 当你第一次看到t-SNE生成的彩色散点图时&#xff0c;可能会被那些看似完美分离的簇所震撼。但当你真正开始在自己的数据集上应用时&#xff0c;却发现结果远不如预期——簇与簇之间模糊不清&#xff0c;甚至完全混在一…...

go-json完全指南:快速替换encoding/json的终极解决方案

go-json完全指南&#xff1a;快速替换encoding/json的终极解决方案 【免费下载链接】go-json Fast JSON encoder/decoder compatible with encoding/json for Go 项目地址: https://gitcode.com/gh_mirrors/go/go-json 想要为你的Go项目带来显著的JSON处理性能提升吗&am…...

FTP、TFTP、HTTP、SMTP、DHCP:应用层协议的核心功能与实战应用解析

1. 应用层协议概述&#xff1a;互联网世界的"翻译官" 如果把互联网比作一个庞大的跨国企业&#xff0c;那么应用层协议就是各部门之间的"翻译官"。它们负责将人类可理解的语言&#xff08;比如点击网页、发送邮件&#xff09;转换成机器能处理的二进制数据…...

FlutterBoost与WebView集成:在Flutter中展示网页内容的完整指南

FlutterBoost与WebView集成&#xff1a;在Flutter中展示网页内容的完整指南 【免费下载链接】flutter_boost FlutterBoost is a Flutter plugin which enables hybrid integration of Flutter for your existing native apps with minimum efforts 项目地址: https://gitcode…...

NOKOV动捕软件数据处理全流程:从MarkerSet建立到刚体生成(附常见问题解决)

NOKOV动捕软件数据处理全流程实战指南 在动作捕捉技术日益普及的今天&#xff0c;NOKOV作为国产动捕软件的代表&#xff0c;其数据处理流程的掌握已成为许多从业者的必备技能。不同于简单的软件操作手册&#xff0c;本文将带您深入理解从原始数据到可用刚体的完整处理逻辑&…...