KMP算法详解

KMP算法用于实现字符串匹配问题。例如查找某个字符串是否是s的子串。

我们先来看一道题

一.力扣28.找出字符串中第一个匹配项的下标

给你两个字符串haystackneedle,请你在haystack字符串中找出needle字符串的第一个匹配项的下标(下标从 0 开始)。如果needle不是haystack的一部分,则返回-1

输入:haystack = "sadbutsad", needle = "sad"输出:0解释:"sad" 在下标 0 和 6 处匹配。 第一个匹配项的下标是 0 ,所以返回 0 。

对于这种题目,我们首先想到的就是使用两个for循环,依次找每一种可能,看看能不能找到匹配的字符串

1.传统for循环

思路:

  • 将主串T(长度为n)与模式串P(长度为m)依次对齐比较。

  • 对齐位置i从 0 到n-m,每次比较T[i..i+m-1]P[0..m-1]

  • 若某个字符不匹配,则模式串向右移动1 位,重新从头比较。

class Solution { public: int strStr(string haystack, string needle) { int n = haystack.length(); int m = needle.length(); // needle 为空字符串的情况 if (m == 0) return 0; // 主循环,尝试所有可能的起始位置 for (int i = 0; i <= n - m; i++) { int j; // 检查当前位置是否匹配 for (j = 0; j < m; j++) { if (haystack[i + j] != needle[j]) { break; } } // 如果完全匹配 if (j == m) { return i; } } //没找到就返回-1 return -1; } };

这种传统解法的时间复杂度是O(n*m),n和m分别是两个字符串的长度,对于最坏的情况,需要搜索n*m次.

那我们可不可以进行优化呢,让搜索的次数减少,以此来降低时间复杂度,当然可以,这就是KMP算法的思想

2.KMP算法

①什么是KMP算法

KMP算法用于实现字符串匹配问题。例如查找某个字符串是否是s的子串。普通方法是从s字符串的开头开始一次比较。时间复杂度O(n*m)。KMP该是该方法的优化方法

KMP算法的核心思想,就是每次如果字符串没有匹配成功,不是从头开始重新查找,而是从一个特定的合理位置开始继续查找,减少了查找次数

那我们应该如何去找到这个特定的合理位置呢,这就是KMP算法的关键,引入一个前缀表的概念

②前缀表

前缀表:记录下标i之前(包括i)的字符串中,有多大长度的相同前缀后缀。

前缀是指不包含最后一个字符,以第一个字符开头的连续子串。

后缀是指不包含第一个字符,以最后一个字符结尾的连续子串

前缀表要求的就是相同前后缀的长度

字符串a的最长相等前后缀为0。 字符串aa的最长相等前后缀为1。 字符串aaa的最长相等前后缀为2。

③next数组

KMP算法就是把子串中的每个位置对应的最长相同前后缀长度,记录在next数组中,一旦匹配失败,就从当前已匹配位置的最长前缀长度继续进行匹配(next[i-1])

④代码实现

1)构建next数组

构建next数组的过程,实际上就是子串自己进行KMP算法的过程

void getNext(vector<int>& next, string& needle) { //初始化最大前后缀长度 int j = 0; //第一个位置的字母相同前后缀长度是0 next[0] = 0; //开始循环查找 for (int i = 1;i < needle.size();i++) { //如果不同,就从已经匹配的最大位置开始重新匹配,直到匹配成功 while (j > 0 && needle[i] != needle[j]) { j = next[j - 1]; } //如果相同,就将前后缀长度+1 if (needle[i] == needle[j]) { j++; } //给当前位置赋值 next[i] = j; } }
2)查找第一个匹配项位置
int KMP(string s, string s1) { //字符串为空或者子串长度更大都是错误的 if (s1.size() == 0 || s.size() == 0 || s.size() < s1.size()) { return -1; } //初始化next数组 vector<int>next(s1.size(),0); //调用方法得到next数组 getNext(next, s1); //开始查找 int j = 0; for (int i = 0;i < s.size();i++) { //和构建next数组一样,如果不匹配,就从已匹配的最长位置重新开始 while (j > 0 && s[i] != s1[j]) { j = next[j - 1]; } //如果相同,就将已匹配长度+1 if (s[i] == s1[j]) { j++; } //终止条件是已匹配长度和子串长度相等,说明全部匹配 if (j == s1.size()) { return i - s1.size() + 1; } } return -1; }
3)举一反三

如果题目要求查找所有匹配项,就将KMP函数中查找成功的部分改为

vec.push_back(i - s1.size() + 1);//存储结果 j=next[j-1];//继续查找
4)效率分析

对于传统的双重for循环的O(n*m)的时间复杂度,KMP算法可以将其降至O(n+m),大大优化了传统方法

在最坏的情况下,如子串是ac,父串是aaa...ac时效果更加明显

3.方法比较

算法时间复杂度空间复杂度优点缺点
暴力匹配O(n × m)O(1)实现简单,代码短最坏情况下效率低
KMPO(n + m)O(m)效率高,适合长字符串实现复杂,需要额外空间

二.KMP算法小结

  • 核心是最长公共前后缀(LPS),用于跳过已匹配部分。

  • next数组是预处理的移位/变形。

  • 匹配时主串指针不回退,模式串指针根据next回退。

  • 适合在流式文本中匹配,因为不需要全文存储。

KMP算法属于比较抽象难想的算法,建议画一画,模拟一下整个过程来帮助理解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1175524.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

YOLO11权重加载失败?路径问题避坑指南

YOLO11权重加载失败&#xff1f;路径问题避坑指南 在使用YOLO11进行目标检测任务时&#xff0c;许多开发者都曾遇到过“权重加载失败”的报错。这类问题往往并非模型本身的问题&#xff0c;而是由文件路径配置不当、环境变量缺失或目录结构混乱等工程化细节引发的。尤其在多平…

LobeChat情感分析功能:识别用户情绪并回应

LobeChat情感分析功能&#xff1a;识别用户情绪并回应 1. 技术背景与应用场景 随着人工智能在人机交互领域的深入发展&#xff0c;聊天机器人不再满足于简单的问答响应&#xff0c;而是朝着更具“共情能力”的方向演进。情感分析作为自然语言处理中的关键能力&#xff0c;能够…

ComfyUI构图优化:基于美学法则的布局建议系统

ComfyUI构图优化&#xff1a;基于美学法则的布局建议系统 1. 引言&#xff1a;ComfyUI与图像生成中的构图挑战 在当前AI图像生成技术快速发展的背景下&#xff0c;ComfyUI作为一款高效、灵活的工作流设计工具&#xff0c;正被越来越多的创作者用于构建复杂的生成流程。其基于…

买不起GPU怎么办?Qwen-Image-2512云端体验2块钱搞定

买不起GPU怎么办&#xff1f;Qwen-Image-2512云端体验2块钱搞定 对于艺术院校的学生来说&#xff0c;创作出惊艳的作品集是通往梦想的敲门砖。然而&#xff0c;顶级显卡动辄上万的价格&#xff0c;让很多学生望而却步。学校机房老旧的设备又无法运行最新的AI模型&#xff0c;眼…

为什么选JPEG格式?UNet抠图中的实用小知识

为什么选JPEG格式&#xff1f;UNet抠图中的实用小知识 在图像处理领域&#xff0c;尤其是基于深度学习的智能抠图任务中&#xff0c;输出格式的选择往往直接影响最终效果与使用场景。本文围绕“CV-UNet 图像抠图”这一高效工具&#xff08;镜像名称&#xff1a;cv_unet_image-…

bge-large-zh-v1.5向量数据库:与Milvus/Pinecone集成指南

bge-large-zh-v1.5向量数据库&#xff1a;与Milvus/Pinecone集成指南 1. 引言 随着大模型应用的不断深入&#xff0c;高效、精准的语义检索能力成为构建智能系统的核心需求。在中文场景下&#xff0c;bge-large-zh-v1.5作为一款高性能的文本嵌入&#xff08;Embedding&#x…

verl法律咨询助手:合规性强化训练部署

verl法律咨询助手&#xff1a;合规性强化训练部署 1. verl 介绍 verl 是一个灵活、高效且可用于生产环境的强化学习&#xff08;RL&#xff09;训练框架&#xff0c;专为大型语言模型&#xff08;LLMs&#xff09;的后训练设计。它由字节跳动火山引擎团队开源&#xff0c;是 …

YOLOv10性能全测评:官方镜像在边缘设备表现如何

YOLOv10性能全测评&#xff1a;官方镜像在边缘设备表现如何 随着实时目标检测在智能监控、工业质检和自动驾驶等场景中的广泛应用&#xff0c;模型的推理效率与部署便捷性已成为工程落地的核心考量。2024年发布的 YOLOv10 以“端到端无NMS”架构重新定义了YOLO系列的极限&…

LangFlow技术揭秘:为什么它能提升LangChain开发效率10倍?

LangFlow技术揭秘&#xff1a;为什么它能提升LangChain开发效率10倍&#xff1f; 1. 引言&#xff1a;低代码时代的AI应用构建新范式 随着大模型技术的快速发展&#xff0c;LangChain 已成为构建基于语言模型的应用程序的核心框架之一。然而&#xff0c;传统的 LangChain 开发…

BGE-Reranker API开发指南:免部署直接调用,1元起试

BGE-Reranker API开发指南&#xff1a;免部署直接调用&#xff0c;1元起试 你是不是也遇到过这样的情况&#xff1a;作为前端工程师&#xff0c;项目里需要接入一个智能搜索或问答功能&#xff0c;后端同事说要用RAG&#xff08;检索增强生成&#xff09;架构&#xff0c;还提…

Wan2.2-T2V-A5B快速部署:企业级内容工厂的低成本启动方案

Wan2.2-T2V-A5B快速部署&#xff1a;企业级内容工厂的低成本启动方案 1. 背景与技术定位 在当前短视频内容需求爆发式增长的背景下&#xff0c;企业对高效、低成本的内容生成工具提出了更高要求。传统视频制作流程依赖专业团队和长时间渲染&#xff0c;难以满足高频次、多样化…

UNet人像卡通化元宇宙身份系统:虚拟世界形象创建基础

UNet人像卡通化元宇宙身份系统&#xff1a;虚拟世界形象创建基础 1. 功能概述 本工具基于阿里达摩院 ModelScope 的 DCT-Net 模型&#xff0c;结合 UNet 架构设计&#xff0c;实现高效、高质量的人像卡通化转换。该系统可作为元宇宙中用户虚拟身份构建的基础组件&#xff0c;…

Qwen3-Reranker-0.6B新手指南:云端环境免配置,一看就会

Qwen3-Reranker-0.6B新手指南&#xff1a;云端环境免配置&#xff0c;一看就会 你是不是也和我一样&#xff0c;曾经是个敲代码的“老手”&#xff0c;如今退休在家&#xff0c;想趁着AI这股热潮再学点新东西&#xff1f;但现实是&#xff1a;笔记本是五年前的老款&#xff0c…

Qwen3-VL-WEB部署教程:1M上下文扩展可行性验证步骤

Qwen3-VL-WEB部署教程&#xff1a;1M上下文扩展可行性验证步骤 1. 引言 随着多模态大模型在视觉理解、语言生成和跨模态推理能力上的持续演进&#xff0c;Qwen3-VL作为通义千问系列中功能最强大的视觉-语言模型&#xff0c;已在多个维度实现显著升级。其原生支持256K上下文长…

SAM3医疗影像分析:合规云端方案免去设备采购

SAM3医疗影像分析&#xff1a;合规云端方案免去设备采购 你是不是也遇到过这样的情况&#xff1f;作为一名诊所医生&#xff0c;每天面对大量X光片、CT扫描和超声图像&#xff0c;想借助AI提升诊断效率&#xff0c;但又面临几个现实难题&#xff1a; 医疗数据高度敏感&#x…

Qwen All-in-One如何工作?指令遵循机制详解教程

Qwen All-in-One如何工作&#xff1f;指令遵循机制详解教程 1. 章节概述 1.1 技术背景与问题提出 在边缘计算和资源受限场景中&#xff0c;部署多个AI模型往往面临显存不足、依赖冲突和启动延迟等问题。传统做法是组合使用专用小模型&#xff08;如BERT用于情感分析&#xf…

IndexTTS-2-LLM技术深度:Sambert引擎与LLM的融合应用

IndexTTS-2-LLM技术深度&#xff1a;Sambert引擎与LLM的融合应用 1. 技术背景与核心价值 随着人工智能在多模态交互领域的持续演进&#xff0c;文本到语音&#xff08;Text-to-Speech, TTS&#xff09;技术正从“能说”向“说得自然、富有情感”迈进。传统TTS系统虽然能够实现…

SAM 3应用案例:电商商品自动分割的完整实现教程

SAM 3应用案例&#xff1a;电商商品自动分割的完整实现教程 1. 引言 随着电商平台商品数量的爆炸式增长&#xff0c;图像处理自动化成为提升运营效率的关键环节。其中&#xff0c;商品图像分割是构建智能商品管理、背景替换、视觉搜索等系统的核心前置步骤。传统方法依赖人工…

视觉语音文本融合处理?AutoGLM-Phone-9B带你玩转跨模态AI

视觉语音文本融合处理&#xff1f;AutoGLM-Phone-9B带你玩转跨模态AI 1. AutoGLM-Phone-9B&#xff1a;移动端多模态大模型的技术突破 1.1 多模态融合的行业需求与技术演进 随着智能终端设备在日常生活和企业场景中的广泛应用&#xff0c;用户对AI助手的交互能力提出了更高要…

Qwen2.5-0.5B实战:智能邮件分类系统开发

Qwen2.5-0.5B实战&#xff1a;智能邮件分类系统开发 随着边缘计算和终端AI的快速发展&#xff0c;轻量级大模型在实际业务场景中的落地价值日益凸显。如何在资源受限的设备上实现高效、准确的自然语言处理任务&#xff0c;成为开发者关注的核心问题。Qwen2.5-0.5B-Instruct 作…