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

字符串匹配——KMP算法

前言
刷到字符串匹配的力扣题了【28. 实现 strStr() 】,这题简单吧用库函数做就可以,说难吧,就得引出大名鼎鼎的线性匹配算法——KMP。

目录

  • KMP
    • 算法背景与原理
    • 算法优势
  • 前缀表
    • 1. 构建Next数组
    • 2. 搜索匹配

KMP

算法背景与原理

KMP(Knuth-Morris-Pratt)算法是一种高效的字符串匹配算法,由Donald Knuth、Vaughan Pratt等人在1977年提出。该算法的核心思想是避免在字符串匹配过程中不必要的回溯,从而提高匹配效率。

在传统的字符串匹配算法中,如Brute Force方法,一旦发现不匹配,模式串会回溯到下一个起始位置重新开始匹配。这种方法在最坏情况下的时间复杂度为O(nm),其中n是主串长度,m是模式串长度。而KMP算法通过预处理模式串,构造一个部分匹配表(也称为next数组),在发生不匹配时,可以跳过已经确认不会匹配的部分,从而提高匹配效率。

核心思想:由传统双层循环遍历入手优化时间复杂度,优化的手段是借助前缀表保证外层索引单向移动。

算法优势

KMP算法的主要优势在于其时间复杂度为O(n+m),相比传统的Brute Force方法,KMP算法在最坏情况下也能保持较高的效率。这是因为KMP算法利用了已经匹配的信息来避免不必要的重复比较。具体来说,KMP算法的优势体现在以下几个方面:

  1. 预处理阶段:KMP算法首先对模式串进行预处理,生成next数组,这一步骤的时间复杂度为O(m)。
  2. 匹配阶段:在匹配过程中,当发现不匹配时,KMP算法利用next数组来决定模式串应该向右移动多少个字符,而不是简单地回溯到下一个字符。
  3. 避免回溯:由于KMP算法能够利用next数组避免不必要的回溯,因此在最坏情况下也能保持较高的效率。

前缀表

在KMP算法中,next数组是一个关键的数据结构,它用于存储模式串中每个位置之前的最长相等前后缀的长度。

1. 构建Next数组

首先,我们需要构建next数组,这个数组将存储模式串中每个位置的最长相同前缀和后缀的长度。我们将next[0]初始化为0,因为模式串的第一个字符没有前缀。

public class KMPMatcher {private String pattern;private int[] next;public KMPMatcher(String pattern) {this.pattern = pattern;next = new int[pattern.length()];computeNext();}// 构建Next数组private void computeNext() {int len = 0; // 最长相等前后缀的长度next[0] = 0; // next[0]初始化为0int i = 1;while (i < pattern.length()) {if (pattern.charAt(i) == pattern.charAt(len)) {len++;next[i] = len;i++;} else {if (len > 0) {len = next[len - 1];} else {next[i] = 0;i++;}}}}
}
  • pattern:模式串,我们需要在其上构建next数组。
  • next:用于存储模式串的部分匹配结果的数组。
  • computeNext方法:计算next数组的值。
    • len:记录当前匹配的最长前后缀的长度。
    • pattern.charAt(i)等于pattern.charAt(len)时,增加leni,并将next[i]设置为len
    • 如果不相等且len大于0,len回溯到next[len - 1]
    • 如果len为0,next[i]设置为0,i增加1。

2. 搜索匹配

接下来,我们使用构建好的next数组来搜索主串中是否存在模式串。

public int search(String text) {int i = 0; // 主串的索引int j = 0; // 模式串的索引while (i < text.length()) {if (j == pattern.length()) {return i - j; // 找到匹配,返回位置} else if (i < text.length() && pattern.charAt(j) == text.charAt(i)) {i++;j++;} else {if (j > 0) {j = next[j - 1];} else {i++;}}}return -1; // 未找到匹配
}
  • search方法:在主串text中搜索模式串pattern
    • ij:分别为主串和模式串的索引。
    • j等于模式串长度时,表示找到匹配,返回匹配的起始位置。
    • text.charAt(i)等于pattern.charAt(j)时,两个索引都增加。
    • 如果字符不匹配且j大于0,根据next数组回溯j
    • 如果j为0,i增加1,继续匹配。

这个实现中,next[0]被初始化为0,这与一些其他实现中next[0]初始化为-1有所不同。这种实现方式在逻辑上更直观,因为next[0]表示模式串的第一个字符没有前缀,所以其长度自然为0。

相关文章:

字符串匹配——KMP算法

前言 刷到字符串匹配的力扣题了【28. 实现 strStr() 】&#xff0c;这题简单吧用库函数做就可以&#xff0c;说难吧&#xff0c;就得引出大名鼎鼎的线性匹配算法——KMP。 目录 KMP 算法背景与原理算法优势 前缀表1. 构建Next数组2. 搜索匹配 KMP 算法背景与原理 KMP&#x…...

Qt开发技术【下拉复选框 MultiSelectComboBox 自定义全选项】

继承ComboBox完成下拉复选框 自定义全选项 效果图 整个控件继承于QCombobox类。主要修改QLineEdit、QListWidget这两部分&#xff0c;QComboBox提供如下接口&#xff0c;可以将这两部分设置为新建的QLineEdit、QListWidget对象 CMultiSelectComboBox::CMultiSelectComboBo…...

20_HTML5 SSE --[HTML5 API 学习之旅]

HTML5 Server-Sent Events (SSE) 是一种技术&#xff0c;它允许服务器向浏览器推送更新。与传统的轮询不同&#xff0c;SSE提供了真正的单向实时通信通道&#xff1a;服务器可以主动发送数据到客户端&#xff0c;而不需要客户端发起请求。这对于实现实时更新的应用非常有用&…...

jetson Orin nx + yolov8 TensorRT 加速量化 环境配置

参考【Jetson】Jetson Orin NX纯系统配置环境-CSDN博客 一 系统环境配置&#xff1a; 1.更换源&#xff1a; sudo vi /etc/apt/sources.list.d/nvidia-l4t-apt-source.list2.更新源&#xff1a; sudo apt upgradesudo apt updatesudo apt dist-upgrade sudo apt-get updat…...

Android Studio IDE环境配置

​需要安装哪些东西&#xff1a; Java jdk Java Downloads | OracleAndroid Studio 下载 Android Studio 和应用工具 - Android 开发者 | Android DevelopersAndroid Sdk 现在的Android Studio版本安装时会自动安装&#xff0c;需要注意下安装的路径Android Studio插件…...

PTA 7-2 0/1背包问题(回溯法) 作者 王东 单位 贵州师范学院

0/1背包问题。给定一载重量为W的背包及n个重量为wi、价值为vi的物体&#xff0c;1≤i≤n,要求重量和恰好为W具有最大的价值。 输入格式: 第一行输入背包载重量W及背包个数n&#xff0c;再依次输入n行&#xff0c;每行为背包重量wi和价值vi。 输出格式: 第一行输出装入背包内…...

Matlab环形柱状图

数据准备&#xff1a; 名称 数值 Aa 21 Bb 23 Cc 35 Dd 47 保存为Excel文件后&#xff1a; % Load data from Excel file filename data.xlsx; % Ensure the file is in the current folder or provide full path dataTable readtable(filena…...

【AI大模型】探索GPT模型的奥秘:引领自然语言处理的新纪元

目录 &#x1f354; GPT介绍 &#x1f354; GPT的架构 &#x1f354; GPT训练过程 3.1 无监督的预训练语言模型 3.2 有监督的下游任务fine-tunning &#x1f354; 小结 学习目标 了解什么是GPT.掌握GPT的架构.掌握GPT的预训练任务. &#x1f354; GPT介绍 GPT是OpenAI公…...

5.Python爬虫相关

爬虫 爬虫原理 爬虫&#xff0c;又称网络爬虫&#xff0c;是一种自动获取网页内容的程序。它模拟人类浏览网页的行为&#xff0c;发送HTTP请求&#xff0c;获取网页源代码&#xff0c;再通过解析、提取等技术手段&#xff0c;获取所需数据。 HTTP请求与响应过程 爬虫首先向…...

Windows系统上配置eNSP环境的详细步骤

华为eNSP&#xff08;Enterprise Network Simulation Platform&#xff09;是一款针对华为数通网络设备的网络仿真平台&#xff0c;用于辅助工程师进行网络技术学习、方案验证和故障排查等工作。以下是在Windows系统上配置eNSP环境的详细步骤&#xff1a; 1. 准备工作 下载安…...

Database.NET——一款轻量级多数据库客户端工具

文章目录 Database.NET简介下载使用使用场景总结 Database.NET简介 Database.NET 是一个功能强大且易于使用的数据库管理工具&#xff0c;适用于多种数据库系统。它为开发者和数据库管理员提供了一个统一的界面&#xff0c;可以方便地管理和操作不同类型的数据库。 支持的数据…...

新浪微博C++面试题及参考答案

多态是什么&#xff1f;请详细解释其实现原理&#xff0c;例如通过虚函数表实现。 多态是面向对象编程中的一个重要概念&#xff0c;它允许不同的对象对同一消息或函数调用做出不同的响应&#xff0c;使得程序具有更好的可扩展性和灵活性。 在 C 中&#xff0c;多态主要通过虚函…...

计算机视觉目标检测-1

文章目录 摘要Abstract1.目标检测任务描述1.1 目标检测分类算法1.2 目标定位的简单实现思路1.2.1 回归位置 2.R-CNN2.1 目标检测-Overfeat模型2.1.1 滑动窗口 2.2 目标检测-RCNN模型2.2.1 非极大抑制&#xff08;NMS&#xff09; 2.3 目标检测评价指标 3.SPPNet3.1 spatial pyr…...

【物联网技术与应用】实验15:电位器传感器实验

实验15 电位器传感器实验 【实验介绍】 电位器可以帮助控制Arduino板上的LED闪烁的时间间隔。 【实验组件】 ● Arduino Uno主板* 1 ● 电位器模块* 1 ● USB电缆*1 ● 面包板* 1 ● 9V方型电池* 1 ● 跳线若干 【实验原理】 模拟电位器是模拟电子元件&#xff0c;模…...

java常用类(上)

笔上得来终觉浅,绝知此事要躬行 &#x1f525; 个人主页&#xff1a;星云爱编程 &#x1f525; 所属专栏&#xff1a;javase &#x1f337;追光的人&#xff0c;终会万丈光芒 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 一、包装类 1.1包装类…...

包管理工具npm、yarn、pnpm、cnpm详解

1. 包管理工具 1.1 npm # 安装 $ node 自带 npm# 基本用法 npm install package # 安装包 npm install # 安装所有依赖 npm install -g package # 全局安装 npm uninstall package # 卸载包 npm update package # 更新包 npm run script #…...

CI/CD是什么?

CI/CD 定义 CI/CD 代表持续集成和持续部署&#xff08;或持续交付&#xff09;。它是一套实践和工具&#xff0c;旨在通过自动化构建、测试和部署来改进软件开发流程&#xff0c;使您能够更快、更可靠地交付代码更改。 持续集成 (CI)&#xff1a;在共享存储库中自动构建、测试…...

[Java]合理封装第三方工具包(附视频)

-1.视频链接 视频版: 视频版会对本文章内容进行详细解释 [Java]合理封装第三方工具包_哔哩哔哩_bilibili 0.核心思想 对第三方工具方法进行封装,使其本地化,降低记忆和使用成本 1.背景 在我们的项目中,通常会引用一些第三方工具包,或者是使用jdk自带的一些工具类 例如: c…...

常规配置、整合IDEA

目录 Redis常规配置 tcp-keepalive security Jedis RedisTemplate 连接池技术 Lua脚本 Jedis集群 Redis应用问题&解决方案 缓存穿透 缓存击穿 缓存雪崩 分布式锁 Redis实现分布式锁 Redis新功能 ACL Redis常规配置 tcp-keepalive security redis.conf中…...

用Python写炸金花游戏

文章目录 **代码分解与讲解**1. **扑克牌的生成与洗牌**2. **给玩家发牌**3. **打印玩家的手牌**4. **定义牌的优先级**5. **判断牌型**6. **确定牌型优先级**7. **比较两手牌的大小**8. **计算每个玩家的牌型并找出赢家**9. **打印结果** 完整代码 以下游戏规则&#xff1a; 那…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

uniapp手机号一键登录保姆级教程(包含前端和后端)

目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号&#xff08;第三种&#xff09;后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...

MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用

文章目录 一、背景知识&#xff1a;什么是 B-Tree 和 BTree&#xff1f; B-Tree&#xff08;平衡多路查找树&#xff09; BTree&#xff08;B-Tree 的变种&#xff09; 二、结构对比&#xff1a;一张图看懂 三、为什么 MySQL InnoDB 选择 BTree&#xff1f; 1. 范围查询更快 2…...

django blank 与 null的区别

1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是&#xff0c;要注意以下几点&#xff1a; Django的表单验证与null无关&#xff1a;null参数控制的是数据库层面字段是否可以为NULL&#xff0c;而blank参数控制的是Django表单验证时字…...

高防服务器价格高原因分析

高防服务器的价格较高&#xff0c;主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因&#xff1a; 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器&#xff0c;因此…...

虚拟机网络不通的问题(这里以win10的问题为主,模式NAT)

当我们网关配置好了&#xff0c;DNS也配置好了&#xff0c;最后在虚拟机里还是无法访问百度的网址。 第一种情况&#xff1a; 我们先考虑一下&#xff0c;网关的IP是否和虚拟机编辑器里的IP一样不&#xff0c;如果不一样需要更改一下&#xff0c;因为我们访问百度需要从物理机…...

AI书签管理工具开发全记录(十八):书签导入导出

文章目录 AI书签管理工具开发全记录&#xff08;十八&#xff09;&#xff1a;书签导入导出1.前言 &#x1f4dd;2.书签结构分析 &#x1f4d6;3.书签示例 &#x1f4d1;4.书签文件结构定义描述 &#x1f523;4.1. ​整体文档结构​​4.2. ​核心元素类型​​4.3. ​层级关系4.…...

易语言是什么?易语言能做什么?

易语言&#xff08;EPL&#xff09;是什么&#xff1f;​​ ​​易语言​​&#xff08;Easy Programming Language&#xff0c;简称EPL&#xff09;是一款​​面向中文用户的编程语言​​&#xff0c;由中国人吴涛于2000年开发&#xff0c;专为降低编程门槛设计。其核心特点是…...