KMP的next数组构建详解
KMP的next数组构建详解
1. next数组的作用
-
核心功能:在KMP算法中,当模式串与主串发生不匹配时,next数组决定模式串指针回退的位置,避免无效匹配。
-
定义:
next[i]表示子串s[0...i]的最长公共前后缀长度。例如,"ABAB"的next[3] = 2(前缀AB和后缀AB)。
2. 代码逐行解析
void getNext(int* next, const std::string& s) {int j = 0; // j指向前缀末尾,初始为0next[0] = j; // 第一个字符无前后缀,长度为0for (int i = 1; i < s.size(); i++) { // 从第二个字符开始处理// 不匹配时,通过next数组回溯jwhile (j > 0 && s[i] != s[j]) { j = next[j - 1]; // 关键:利用已计算的next值回退}// 匹配时,j后移if (s[i] == s[j]) {j++;}// 记录当前i对应的最长公共前后缀长度next[i] = j;}
}
3. 关键问题:为什么用while循环回退?
-
逐步缩短前缀:当
s[i]与s[j]不匹配时,需找到更短的公共前后缀继续尝试。例如,模式串"ABABAC",在i=5(字符C)时,若j=3(字符B),此时需回退到next[2]=1(字符A)继续比较。 -
避免遗漏:使用
while确保所有可能的前缀都被尝试,直到匹配或退到0。若用if,仅回退一次,可能错过有效前缀。
4. 实例演示
模式串:"ABABAC"
步骤分析:
| i | s[i] | 初始j | while循环过程 | 最终j | next[i] | 解释 |
|---|---|---|---|---|---|---|
| 0 | A | 0 | - | 0 | 0 | 初始化 |
| 1 | B | 0 | 不匹配,j保持0 | 0 | 0 | AB无公共前后缀 |
| 2 | A | 0 | s[2]=A匹配s[0] | 1 | 1 | ABA最长公共"A" |
| 3 | B | 1 | s[3]=B匹配s[1] | 2 | 2 | ABAB最长公共"AB" |
| 4 | A | 2 | s[4]=A匹配s[2] | 3 | 3 | ABABA最长公共"ABA" |
| 5 | C | 3 | 两次回退到j=0 | 0 | 0 | ABABAC无公共前后缀 |
最终next数组:[0,0,1,2,3,0]
5. 完整KMP搜索示例
int kmpSearch(const string& text, const string& pattern) {int n = pattern.size();if (n == 0) return 0;int* next = new int[n];getNext(next, pattern);int j = 0; // 模式串指针for (int i = 0; i < text.size(); i++) { // i遍历主串// 不匹配时,回退模式串指针while (j > 0 && text[i] != pattern[j]) {j = next[j - 1];}// 匹配时,后移jif (text[i] == pattern[j]) j++;// 完全匹配时返回起始位置if (j == n) {delete[] next;return i - n + 1;}}delete[] next;return -1;
}
使用示例:
int main() {string text = "ABABABACABABAC";string pattern = "ABABAC";int pos = kmpSearch(text, pattern); // 输出:Pattern found at index 2// 解释:text[2..7] = "ABABAC"与模式匹配
}
6. 总结
-
核心思想:通过模式串自我匹配构建next数组,利用已匹配信息避免重复比较。
-
时间复杂度:O(n+m),n和m分别为模式串和主串长度,远优于暴力法的O(nm)。
-
关键点:理解next数组的动态构建过程,以及如何通过回溯高效寻找最长公共前后缀。
相关文章:
KMP的next数组构建详解
KMP的next数组构建详解 1. next数组的作用 核心功能:在KMP算法中,当模式串与主串发生不匹配时,next数组决定模式串指针回退的位置,避免无效匹配。 定义:next[i]表示子串s[0...i]的最长公共前后缀长度。例如ÿ…...
Docker 的安全配置与优化(二)
Docker 安全优化策略 (一)多阶段构建优化镜像大小 多阶段构建是 Docker 17.05 版本引入的强大功能,它允许在一个 Dockerfile 中定义多个构建阶段,每个阶段都可以使用不同的基础镜像和依赖项,最终只将必要的文件和依赖…...
shiro代码层面追踪
文章目录 环境漏洞分析硬编码 反序列化Gadget构造 环境 环境搭建:https://blog.csdn.net/qq_44769520/article/details/123476443 漏洞分析 硬编码 shiro是对rememberMe这个cookie进⾏反序列化的时候出现了问题。 相应代码 // // Source code recreated from …...
通信系统中物理层与网络层联系与区别
在通信系统中,物理层和网络层是OSI(开放系统互连)模型中的两个重要层次,分别位于协议栈的最底层和第三层。它们在功能、职责和实现方式上有显著的区别,但同时也在某些方面存在联系。以下是物理层与网络层的联系与区别的…...
虚拟机网络ssh连接失败,没有网络
vscode进行ssh时连接失败,发现是虚拟机没有网络。 虚拟机ping不通www.baidu.com但可以ping通内网 ping 8.8.8.8ping不通。 sudo dhclient -r ens33 sudo dhclient ens33 ip route show可以了。 20250221记录:不知道是不是重启了虚拟机还是咋了&#…...
已知点矩阵的三个顶点坐标、行列数和行列的间距,计算得出剩余所有点的坐标
已知点矩阵的三个顶点坐标、行列数和行列的间距,计算得出剩余所有点的坐标 计算矩阵中每个点的坐标代码实现案例图调用验证 计算矩阵中每个点的坐标 给定左上角、左下角和右上角三个点的坐标,以及矩阵的行数、列数、行间距和列间距,我们可以…...
Python Cookbook-2.4 从文件中读取指定的行
任务 根据给出的行号,从文本文件中读取一行数据。 解决方案 Python标准库linecache模块非常适合这个任务: import linecache theline linecache.getline(thefilepath, desired_line_number)讨论 对这个任务而言,标准的 linecache 模块是 Python 能…...
go 并发 gorouting chan channel select Mutex sync.One
goroutine // head: 前缀 index:是一个int的指针 func print(head string, index *int) {for i : 0; i < 5; i {// 指针对应的int *indexfmt.Println(*index, head, i)// 暂停1stime.Sleep(1 * time.Second)} }/* Go 允许使用 go 语句开启一个新的运…...
Unity游戏制作中的C#基础(3)加减乘除算术操作符,比较运算符,逻辑与,或运算符
1. 基本算术运算符 算术运算符主要用于对数值类型(整型和浮点型)进行基本的数学运算。以下是常见的算术运算符及其说明: 运算符描述示例结果加法运算符,用于两个数相加,也可用于字符串连接int a 5 3; string str &…...
深度学习入门--python入门2
以前学的全忘了,现在算是才开始学,有错误,恳请指正。 目录 1.4 Python脚本文件 1.4.1保存为文件 1.4.2 类 1.5 Numpy 1.5.1 导入Numpy 1.5.2 生成Numpy数组 1.5.3 Numpy的算术运算 1.5.4 Numpy的N维数组 1.5.5 广播 1.5.6 访问元素…...
题海拾贝:【枚举】P2010 [NOIP 2016 普及组] 回文日期
Hello大家好!很高兴我们又见面啦!给生活添点passion,开始今天的编程之路! 我的博客:<但凡. 我的专栏:《编程之路》、《数据结构与算法之美》、《题海拾贝》 欢迎点赞,关注! 1、题…...
Mac端homebrew安装配置
拷打了一下午o3-mini-high,不如这位博主的超强帖子,10分钟结束战斗 跟随该文章即可,2025/2/19亲测可行 mac 安装HomeBrew(100%成功)_mac安装homebrew-CSDN博客文章浏览阅读10w次,点赞258次,收藏837次。一直觉得自己写…...
Web - JS基础语法与表达式
概述 这篇文章主要介绍了 JavaScript 的基础语法,包括代码书写位置、ERPL 环境、变量(命名规则、默认值、初始化)、数据类型(基本和复杂,及各类型特点、转换)、表达式和运算符(算数、特殊算数、…...
Python高级语法之selenium
目录: 1、selenium的使用2、selenium元素定位3、selenium使用功能Phantomjs模拟浏览器启动4、selenium使用功能ChromsHandless模拟浏览器启动 1、selenium的使用 2、selenium元素定位 3、selenium使用功能Phantomjs模拟浏览器启动 4、selenium使用功能ChromsHandles…...
AIP-148 标准域
编号148原文链接AIP-148: Standard fields状态批准创建日期2020-10-06更新日期2020-10-06 一些概念在任何API集合中都很常用。对于这些概念,使用统一的标准域名字和行为来表达它们,是非常有用的。 指南 标准域 应当 用于描述其相应概念, 不…...
Docker构建时,设定默认进入的工作目录的方法
在 Docker 中,你可以通过不同的方式来设定容器默认进入的目录,以下针对不同场景分别介绍具体方法: 1. 使用 Dockerfile 设定工作目录 如果你是通过构建镜像的方式来运行容器,那么可以在 Dockerfile 中使用 WORKDIR 指令来设置容器启动时的默认工作目录。以下是具体步骤:…...
2025年3月最新算法-鲸鱼迁徙优化算法Whale Migration Algorithm-附Matlab免费代码
引言 本期介绍了一种基于座头鲸协同迁移行为的创新生物启发式优化方法——鲸鱼迁徙优化算法Whale Migration Algorithm,WMA。该算法于2025年3月最新发表在期刊 Results in Engineering 在本节中,我们概述了开发鲸鱼迁移算法(WMA)…...
day56 第十一章:图论part06
108.冗余连接 注意init初始化 改进: 其实只有一条边冗余,改为,如果两条边在同一个集合里,就输出,不然加入。 #include <iostream> #include <vector> using namespace std;int n 1005; vector<int>…...
flowable适配达梦数据库
文章目录 适配相关问题无法从数据库产品名称“DM DBMS”中推断数据库类型分析解决 构建ibatis SqlSessionFactory时出错:inStream参数为null分析解决 liquibase相关问题问题一:不支持的数据库 Error executing SQL call current_schema: 无法解析的成员访…...
Jenkins整合Jmeter实现接口自动化测试
🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 一、安装jmeter 下载:http://jmeter.apache.org/download_jmeter.cgi 这里我用了一台Windows安装jmeter用来写接口测试的脚本,启动前修改j…...
高级推理的多样化推理与验证
25年2月来自波士顿大学、NotBadMath.AI、谷歌、哥伦比亚大学、MIT、Intuit公司和斯坦福大学的论文“Diverse Inference and Verification for Advanced Reasoning”。 OpenAI o1、o3 和 DeepSeek R1 等推理 LLM 在数学和编码方面取得重大进展,但仍发现 IMO 组合问题…...
深入理解 MySQL 8 C++ 源码:SELECT MOD(MONTH(NOW()), 2) 的函数执行过程
MySQL 作为最流行的关系型数据库之一,其内部实现机制一直是开发者探索的热点。本文将以一条简单的 SQL 查询 SELECT MOD(MONTH(NOW()), 2) 为例,深入分析 MySQL 8 源码中内置函数 MOD、MONTH 和 NOW 的执行过程,揭示其底层实现逻辑。 一、SQL…...
清华大学:DeepSeek与AI幻觉(31页PDF)
PDF深入探讨了AI幻觉的概念、原因、评测方法及其实用应用,特别是在金融领域的具体案例。首先介绍了AI幻觉的定义,主要包括数据偏差、泛化困境、知识固化和意图误解四种情况,以及这些因素导致AI产出不合理结果的原因。随后,通过音乐…...
AWS云从业者认证题库 AWS Cloud Practitioner(2.21)
题库持续更新,上方二维码查看完整题库! 公司希望减少开发人员用于运行代码的物理计算资源,通过启用无服务器架构,哪种服务可以满足该需求? A: Amazon Elastic Compute Cloud (Amazon EC2) B: AWS Lambda C:…...
CompletableFuture 使用和源码解读
引言 CompletableFuture 是 Java 8 引入的一个强大的异步编程工具,用于处理异步操作和处理结果。它实现了 Future 和 CompletionStage 接口,提供了丰富的方法来处理异步任务的完成、组合和异常处理。 CompletableFuture本质是对异步线程的返回值…...
C++与Python:两种编程语言的区别
C和Python都是当今编程领域广泛使用的语言,它们各有特色,适用于不同的开发场景。本文将从语言特性、性能、学习难度、应用领域等多个方面探讨C与Python之间的区别。 一、语言特性 类型系统: C:是一种静态类型语言…...
网络工程师 (43)IP数据报
前言 IP数据报是互联网传输控制协议(Internet Protocol,IP)的数据报格式,由首部和数据两部分组成。 一、首部 IP数据报的首部是控制部分,包含了数据报传输和处理所需的各种信息。首部可以分为固定部分和可变部分。 固定…...
京准电钟:水利控制系统网络时间同步设计与应用
京准电钟:水利控制系统网络时间同步设计与应用 京准电钟:水利控制系统网络时间同步设计与应用 引言 在水利工程中,控制系统的高效运行依赖于精准的时间同步。水电站、泵站、闸门控制、水文监测等子系统的协同作业需要毫秒甚至微秒级的时间…...
QML 实现一个动态的启动界面
QML 实现一个动态的启动界面 一、效果查看二、源码分享三、所用到的资源下载 一、效果查看 二、源码分享 工程结构 main.qml import QtQuick import QtQuick.Controls import QtQuick.Dialogs import Qt.labs.platformWindow {id:windowwidth: 640height: 400visible: truetit…...
伪404兼容huawei生效显示404
根据上述思考,以下是详细的中文分步说明: --- **步骤 1:获取目标设备的User-Agent信息** 首先,我们需要收集目标设备的User-Agent字符串,包括: 1. **iPhone设备的User-Agent**: Mozi…...
