首页 > 编程语言 >KMP算法

KMP算法

时间:2024-03-27 21:56:34浏览次数:34  
标签:子串 匹配 前缀 后缀 next 算法 KMP 长度

​ 应用于字符串匹配,主要思想就是当出现字符串不匹配时,可以知道一部分之前已经匹配的文本内容,利用这些信息避免从头再做匹配。

如何利用已经匹配的文本内容?前缀表

前缀表:用来回退,记录模式串与主串(文本串)不匹配的时候,模式串应该从哪里开始重新匹配。记录下标i之前(包括i)的字符串中,有多大长度的相同前缀后缀。

前缀:不包含最后一个字符的所有以第一个字符开始的连续子串

后缀:不包含第一个字符的所有以最后一个字符结尾的连续子串

example:

文本串: a a b a a b a a f a

模式串: a a b a a f

匹配的过程中文本串b和模式串f 不匹配,而模式串f之前的部分字符串(aabaa)的最长相等的前缀和后缀字符串是字符串aa,因为找到了最长相等的前缀和后缀,匹配失败的位置是后缀子串后面,我们可以找到与其相同的前缀的后面重新匹配即可,这样避免匹配失败就从头匹配的复杂度过高问题,利用了已经匹配的信息。

如何计算前缀表

example: a a b a a f

对于前1个字符的子串a, 最长相同前后缀长度为0

对于前2个字符的子串a a, 最长相同前后缀长度为1

对于前3个字符的子串a a b, 最长相同前后缀长度为0

对于前4个字符的子串a a b a, 最长相同前后缀长度为1

对于前5个字符的子串a a b a a , 最长相同前后缀长度为2

对于前6个字符的子串a a b a a f, 最长相同前后缀长度为0

前缀表和模式串联系在一起,具体如图

前缀表与next数组:next数组可以是前缀表,也可以是前缀表统一减一

时间复杂度分析:设文本串长度为n, 模式串长度为m,匹配的过程中不断根据前缀表调整匹配的位置,可以看出匹配的过程是O(n)(因为前缀表使得文本串中不需要回退位置,只需要每次从匹配错误的位置重新匹配,因此是O(n),位置调整是基于模式串调整的),单独生成next数组需要时间复杂度O(m),整个KMP算法的时间复杂度是O(n+m)的。

构造next数组:计算模式串的前缀表:

统一减一的前缀表:与索引相匹配
点击查看代码
void getNext(int* next, const string& s){
    int j = -1;
    next[0] = j;
    for(int i = 1;i < s.size();i++){
        while(j>=0 && s[i]!=s[j+1]){
            j = next[j];    
          }
        if(s[i]==s[j+1]){
            j++;
          }
        next[i]=j;
   }
};

与前缀长度相匹配:

点击查看代码
void getNext(int* next, const string& s){
    int j = 0;
    next[0] = j;
    for(int i = 1;i<s.size();i++){
        while( j > 0 && s[i] != s[j]){
            j = next[j-1]; 
        }
        if(s[i] == s[j]){
            j++;
        }
        next[i] = j;
    }
}
![](/i/l/?n=24&i=blog/3108144/202403/3108144-20240327214538436-912147102.png)

标签:子串,匹配,前缀,后缀,next,算法,KMP,长度
From: https://www.cnblogs.com/perngfey-note/p/18095672

相关文章

  • ADAS多传感器后融合算法解析-上篇
    ADAS多传感器后融合算法解析-上篇附赠自动驾驶学习资料和量产经验:链接ADAS系统是一种高自动化的软件应用,对系统的鲁棒性与可靠性要求很高,单一传感器往往存在一定限制,此时便需要多传感器融合。多传感器融合会带来如下收益:可以在部分场景提升整体感知精度。某一传感器出现......
  • ADAS多传感器后融合算法解析-下篇
    ADAS多传感器后融合算法解析-下篇在ADAS多传感器后融合(上)中我们介绍了后融合的接口、策略。本文将主要介绍后融合的实现流程、难点及注意事项。附赠自动驾驶学习资料和量产经验:链接二、后融合处理流程如下图为基本RC后融合系统流程图,接下来将介绍各个模块:如下图为Apollo......
  • (2-3-4)位置控制算法:无人机运动控制系统——基于非线性动力学和积分滑模控制的仿真测试
    2.3.6 基于非线性动力学和积分滑模控制的仿真测试文件test/fault_ISMC.py实现了一个基于非线性动力学模型的无人机控制系统仿真环境,其中包括飞行器模型、故障注入、和控制器。旨在帮助开发者理解和评估基于积分滑模控制的无人机控制系统在执行器故障条件下的行为。classEn......
  • 欧拉函数、快速幂、扩展欧几里得算法、中国剩余定理
     数据结构、算法总述:数据结构/算法C/C++-CSDN博客欧拉函数欧拉函数(Euler'stotientfunction)是一个与正整数n相关的数论函数,通常用φ(n)表示。定义为小于或等于n的正整数中与n互质的数的个数intphi(intx){intres=x;for(inti=2;i<=x/i;i++)......
  • DDPG强化学习算法应用到TORCS仿真平台
    一、DDPG算法介绍1.前身DQN算法在介绍DDPG算法之前,需要首先明确它的前身DQN算法。DQN(DeepQ-Network)是一种用于强化学习的深度学习算法,由DeepMind公司开发。它结合了深度学习和Q-learning算法,旨在解决复杂环境下的强化学习问题。DQN算法在解决复杂环境下的强化学习问题方面取......
  • 3.27 算法补全:行列式(扩展)
    行列式Ex海森堡矩阵行列式上海森堡阵是满足其次对角线下的值都为\(0\),即只有\(i\lej+1\)处的\(a_{i,j}\)的矩阵。上海森堡阵的行列式可以\(O(n^2)\)DP求解,因为在这个矩阵中选择一个不含\(0\)的排列,一定满足会形成如下形式:\(x,1,2,\dots,x-1\midy,x+1,\dots,y-1\mi......
  • 文心一言 VS 讯飞星火 VS chatgpt (223)-- 算法导论16.3 5题
    五、证明:如果我们将字母表中字符按频率单调递减排序,那么存在一个最优编码,其码字长度是单调递增的。文心一言:为了证明这个结论,我们可以使用霍夫曼编码(HuffmanCoding)作为示例,它是一种广泛使用的最优前缀编码方法。霍夫曼编码满足题目中的要求:如果我们将字母表中字符按频率......
  • Java开发千万别错过的好课程:Java版数据结构和算法+AI算法课程13
    AI人工智能时代,Java从业者必学科目精品课程推荐:Java版数据结构和算法+AI算法课程【点击开始学习】工作机会推荐和资源分享群:819391432学习地址:https://class.imooc.com/sale/fullstackalgo在当今数字时代,数据已成为驱动创新和决策的关键资源。为了在这个竞争激烈的世界......
  • 动态规划刷题(算法竞赛、蓝桥杯)--数字三角形(线性DP)
    1、题目链接:[USACO1.5][IOI1994]数字三角形NumberTriangles-洛谷#include<bits/stdc++.h>usingnamespacestd;intr;constintN=1010;inta[N][N];intmain(){ cin>>r; for(inti=1;i<=r;i++){ for(intj=1;j<=i;j++){ cin>>a[i][j]; ......
  • 网上的一个用C语言实现FFT算法
     用C语言实现FFT算法/*****************fftprograme*********************/#include"typedef.h"#include"math.h"structcompxEE(structcompxb1,structcompxb2){structcompxb3;b3.real=b1.real*b2.real-b1.imag*b2.imag;b3.imag=b1.real*b2.imag+b1.imag*b2.real;......