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

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())
    }
    

相关文章:

  • 4.多表查询
  • Vue3集成百度实时语音识别
  • 工业相机中CCM使能参数-色彩校正矩阵
  • MYSQL-库的基本操作
  • SpringBoot项目,密码加密之“BCrypt加密”
  • SSM公廉租房维保系统
  • 多智能体系统的中间件架构
  • 策略模式:动态切换算法的设计智慧
  • 在Linux中如何通过nohup命令监控进程状态
  • 桌面快捷图标左下角有蓝色问号解决方法
  • 将十六进制字符串转换为二进制字符串的方法(Python,C++)
  • ZYNQ笔记(十三):双核 AMP 通信实验
  • 【IDEA】怎么修改IDEA的JDK版本
  • tomcat远程Debug
  • 3.1 Agent定义与分类:自主Agent、协作Agent与混合Agent的特点
  • 高等数学第一章---函数与极限(1.3 函数的极限)
  • 海量粒子特效解决方案:VEG
  • Java线程中断机制详解
  • JAVA设计模式——(三)桥接模式
  • 桥接模式:分离抽象与实现的独立进化
  • 更好发挥汽车产业在扩投资促消费方面的带动作用!陈吉宁调研上海车展
  • 宁德时代与广汽等五车企发布10款巧克力换电新车型:年内将将完成30城1000站计划
  • 港澳航天员最早2026年飞天
  • 中国墨西哥商会副执行主席:深耕中国市场18年,对未来充满信心
  • 译者手记|如何量化家庭历史
  • 辽宁一季度GDP为7606.9亿元,同比增长5.2%