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

2026《数据结构》考研复习笔记六(串的KMP算法)

KMP算法

  • 前言
  • 一、KMP算法详解
  • 二、重要函数
    • 1.next数组
    • 2.next数组优化
    • 3.KMP算法

前言

本文章主题思路取自leetcode中关于KMP算法的讲解,外加笔者本人的一些感悟。为了便于读者阅读方便,节省跳转的时间,在此直接粘贴leetcode的讲解内容。关于KMP的三个函数是笔者结合王道《2025数据结构》 的函数(不完全符合)总结的,其中 关于next数组的感悟写在了next函数注释中——便于快速理解其原理,方便考试快速写出next函数并且解决匹配问题

一、KMP算法详解

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、重要函数

有几个关键记忆点要注意一下:

  1. next[i]存储的是下一个要匹配的字符,所以当匹配失败后j = next[j];即可直接进行下一次匹配
  2. whlie循环中(j== -1||p[i]== p[j])(求next数组)(j== -1||s[i]== p[j])(s与p匹配)中:
  • j==-1:子串第一个字符匹配失败,因此子串和母串都要进位
  • s[i]== p[j]:子串和母串匹配成功,因此子串和母串都要进位
  • 3. 如果匹配失败,则跳转到next[j],匹配下一个字符,直到第一个字符匹配失败,跳转到-1 4. 关于next的优化:如果跳转到的next[j]和上一个匹配失败的j位置的字符一样,则没有必要匹配,直接跳转next[j]的next[next[j]],直接在进行next数组初始化时完成该步。由于先前的next已经完成了优化,因此后面的next只需要检查当前的字符和要跳转的位置是否相同即可(动态规划)

    1.next数组

    void getNext(const string& p, vector<int>&next) {//next[i]存储的是下一个要匹配的字符,而不是最长公共前后缀的最后一个字符int i = 0;//虽然初始化为0,但是稍后便进行i++,因为第一个字符串没有公共前后缀,直接匹配失败int j = -1;//第一个字符匹配失败next[0] = -1;//如果第一个字符串匹配失败,则无法再转跳到下一个子匹配串的匹配字符,只能赋值为-1,通过while循环进行i++,j++//由此可见,求next数组的时候,本质也是一种字符串匹配while (i < p.length()) {if (j == -1 || p[i] == p[j]) {//第一个字符匹配失败或当前字符匹配成功i++; j++;//i和j变成下一个要匹配的字符next[i] = j;//记录i前面的最长公共前后缀的长度}else {j = next[j];//跳转到下一个要匹配的字符,大部分是0,表示匹配第一个字符,只有第一个字符是-1,表示彻底匹配失败}}
    }
    

    2.next数组优化

    防止子串下一个匹配字符和上一个失败匹配字符相同,直接进入下一个不同的字符位置

    void getNextVal(const string& p, vector<int>& nextVal) {int i = 0;int j = 0;nextVal[0] = -1;while (i < p.length()) {if (j == -1 || p[i] == p[j]) {i++; j++;if (p[i] != p[j])nextVal[i] = j;else nextVal[i] = nextVal[j];//防止子串下一个匹配字符和上一个失败匹配字符相同,直接进入下一个不同的字符位置}else {j = nextVal[j];}}
    }
    

    3.KMP算法

    int Kmp(const string& s, const string& p, const vector<int>& next) {int indexS = 0;int indexP = 0;while (indexS < s.length() && indexP < p.length()) {if (indexP == -1 || s[indexS] == p[indexP]) {//第一个字符匹配失败或当前字符匹配成功indexS++, indexP++;}else {indexP = next[indexP];}}if (indexP < p.length())return 0;return indexS - p.length() + 2;//返回匹配字符串的首字母在母串的位置(1<=index<=s.length())
    }
    
http://www.xdnf.cn/news/1489.html

相关文章:

  • 【网工第6版】第5章 网络互联⑥
  • 《MySQL:MySQL表的内外连接》
  • 【Redis】redis主从哨兵
  • MySQL常见问题解答
  • 【异常解决】Spring Boot 返回排序后的 Map 但前端接收顺序不对的解决方案
  • C++类与继承
  • SpringBoot中6种自定义starter开发方法
  • 同z科技面经
  • Python爬虫第18节-动态渲染页面抓取之Splash使用上篇
  • Sci期刊的编辑会对投稿论文进行查重吗?
  • 【深度学习与大模型基础】第13章-什么是机器学习
  • CSGO 盲盒开箱系统技术实现深度解析
  • Spring Boot + MyBatis 动态字段更新方法
  • ToDesk远程开机设置指南(适用于HP台式机)
  • 网络安全零基础培训 L1-7 Web基础和CSS渲染
  • C++入门小馆: 探寻vector类
  • 配置 Nginx 的 HTTPS
  • 【已解决】Chrome开发工具栏无法看到React Developer Tools
  • Visium HD多样本拼片拆分
  • 基于 Skynet Cluster 模式的完整案例
  • 【TUST“码蹄杯”编程之星】4.23 每日一题
  • Spring Boot 请求参数接收控制指南
  • 有源晶振波形特性与测量分析
  • 【Deepseek学习大模型推理】MOONCAKE: A KVCache-centric Architecture 第一部分引言部分
  • Java 异常 SSLException: fatal alert: protocol_version 全解析与解决方案
  • 多智能体系统的中间件架构
  • 爬虫学习总结
  • 02.Python代码Pandas - Series全系列分享(使用.特点.说明.取值.函数)
  • AIGC vs 人类创作者:是竞争还是协作?
  • Python基础语法3