Python KPM算法

article/2025/10/9 8:31:03

知识点说明:

先说前缀,和后缀吧

比如有一个串:abab

则在下标为3处的(前缀和后缀都要比下标出的长度小1,此处下标为3出的长度是4)

前缀为:a,ab,aba

后缀为:b,ba,bab

一、要获取KPM算法的next[]数组

简单说一下原理吧,首先k,用来存放前缀的下标,首先初始化j=0(j用来表示模式串的下标,一直去模式串的每一位与前面的进行比较,如果相等,则记录下当前位置与前面的哪个位置相同,我们这里主要是要记录相同位置的下一个位置,就是不相同的位置,从不相同的位置开始比较,就是回溯到不相同位置,所以这里在t[j]==t[k]成立的时候要j+1,为了比较下一个位置是否相同,k也要+1),模式串从0开始,k=-1,next[0]=-1第一个位置赋默认值-1;

此处串采用=“abab”

第一次循环:

判断k是否等于-1,如果等于则,j和k都+1,

此时j=1,k=0,next[1]=0,也就是第2个位置(下标1)的回溯位置还是0,因为前缀的最大长度必须小于当前位置的长度;

第二次循环:

j=1,k=0,next[1]=0;k已经不等于-1了,判断t[j]==t[k],t[1]==t[0],t[1]="b",t[0]="a",不相等

执行else:

k=next[0]=-1

第三次循环:

k==-1

j和k都+1,j=2,k=0,next[2]=0

第四次循环:

k不等于-1,判断t[2]==t[0],t[2]=“a”=t[0]=“a”,成立

j和k都+1,j=3,k=1,next[3]=1

此时next=[-1,0,0,1],next[3]=1表示在next[3]处发生不匹配时,也就是模式串下标为3时为“b”,说明前面aba都是和目标串都匹配,所以模式串不匹配位置前面的串aba一定与目标串不匹配位置前面的前3个值相等,也就是aba,所以此刻,只需要回溯到模式串的1位置,也就是模式串的b,模式串b前面是a,满足目标串的前一个a。

第五次循环:

k依旧是不等于-1,就是比较上一个位置后面的两个数再进行比较,简单的说,以此取出每一项与第一项比较,如果存在相等的就再比较下一个与第二项是否相等。

代码如下:

def GetNext(t, next):j, k = 0, -1next[0] = -1while j < len(t) - 1:if k == -1 or t[j] == t[k]:  # 如果k==-1 或者 开始位置和结尾位置有相同的元素j, k = j + 1, k + 1  # j和k都加1,当前位匹配,则从下一个位置开始匹配,所以k+1;j再进行取下一位判断是否也是匹配,所以也要+1next[j] = k  # 当前位置要取k项else:#如果不相等,再把k置-1,下一次循环再进行+1操作,j这个位置再存入0,表示无匹配项k = next[k]return next

二、KMP函数

原理和BF算法是一样的,唯独不同的是,当模式串与目标串不匹配的时候,不直接回溯模式串,而是根据模式串的next[]表,查询要回溯到的位置,直接回溯到模式串的指定位置,KMP算法的核心也就在这里,但是这种方法一般只对前缀和后缀存在相同元素时,有效果,也就是说相同部分是一样的就不再进行比较了,从相同元素的下一个位置开始比较,所以KMP算法最复杂的部分其实就是找next[]表,要找出模式串的每一个位置,是否有相同前缀,如果有则标注该相同位置,下次回溯就不用回溯到0这个位置,可以从不相同位置开始。

def KMP(s, t):next = [0] * len(t)next = GetNext(t, next)print(next)i, j = 0, 0while i < len(s) and j < len(t):if j == -1 or s[i] == t[j]:i, j = i + 1, j + 1else:j = next[j]if j >= len(t):return i - len(t)else:return -1

完整代码:

def GetNext(t, next):j, k = 0, -1next[0] = -1while j < len(t) - 1:if k == -1 or t[j] == t[k]:  # 如果k==-1 或者 开始位置和结尾位置有相同的元素j, k = j + 1, k + 1  # j和k都加1,当前位匹配,则从下一个位置开始匹配,所以k+1;j再进行取下一位判断是否也是匹配,所以也要+1next[j] = k  # 当前位置要取k项else:#如果不相等,再把k置-1,下一次循环再进行+1操作,j这个位置再存入0,表示无匹配项k = next[k]return nextdef KMP(s, t):next = [0] * len(t)next = GetNext(t, next)print(next)i, j = 0, 0while i < len(s) and j < len(t):if j == -1 or s[i] == t[j]:i, j = i + 1, j + 1else:j = next[j]if j >= len(t):return i - len(t)else:return -1if __name__ == '__main__':re = KMP('asdfghjsssaaasdfaaaabababcdabd', "ababaaaababaa")print(re)

结果:

 


http://chatgpt.dhexx.cn/article/DHZGDmF3.shtml

相关文章

KPM算法——数据结构|复习局|串|复杂模式匹配算法|二维数组解决KPM

数据结构复习局——KPM算法 何为KPM&#xff1f;事先规则状态匹配dp——状态转移图状态X获得dp数组值看看图再理解下 写在前面&#xff1a; 本文仅为作者个人学习记录&#xff0c;详细具体内容参考自知乎大佬labuladong &#x1f448;点击与大佬&#x1f93a;击剑&#x1f93a;…

KMP算法原理及实例

KMP是为了解决串的匹配问题。 一、基础知识 1、概念 1.串的匹配问题&#xff1a;就是在一个长的主串s中找到另一个的短的子串t。 2.目标串&#xff08;主串\文本串&#xff09;&#xff1a;被匹配的母串&#xff0c;串s被称为目标串。 3.模式串(子串&#xff09;&#xff1a…

KPM算法思想及实现

一、比较暴力算法和KMP算法 1、暴力算法&#xff1a; 双指针遍历主串和子串&#xff0c;当发现主串和子串不匹配时&#xff0c;双指针同时回溯 2、KMP算法&#xff1a; 双指针遍历主串和子串&#xff0c;当发现主串和子串不匹配时&#xff0c;通过比较子串的next数组只回溯…

正定矩阵的性质

正定矩阵的定义&#xff1a;若矩阵A是n阶方阵&#xff0c;并且它的二次型大于0&#xff0c;即&#xff0c;则矩阵A是正定矩阵。 正定矩阵的性质&#xff1a; 正定矩阵的所有特征值都为正数。正定矩阵行列式为正数两个正定矩阵的和为正定矩阵&#xff08;两个正定矩阵的乘积不…

顺序主子式

设A为 阶矩阵&#xff0c;子式 称为A的i阶顺序主子式。 [1] 对于 阶的矩阵A&#xff0c;其共有n阶顺序主子式&#xff0c;即矩阵A的顺序主子式由 共n个行列式按顺序排列而成。

【矩阵论笔记】平方根分解

定义 例子 首先判断顺序主子式。 R矩阵每一行除以对角元 平方根分解推导 因为A的分解是唯一的&#xff0c;可以得到 L R T LR^{T} LRT 例题 待定系数法

MATLAB_数值计算_用平方根法解线性方程组—(Cholesky分解)

利用对称正定矩阵的乔累斯基分解求解对称正定方程组的方法称为平方根法对称正定矩阵A的对角元为正实对称矩阵A正定的充要条件是A的所有特征值为正对称正定矩阵非奇异&#xff0c;其逆亦为对称正定矩阵实对称矩阵A正定的充要条件是A的所有顺序主子式为正正定矩阵的顺序主子阵是正…

正定与半正定矩阵,判别的方法不能混用,否则出错

坑&#xff1a;特征值有0可以知道该矩阵不可能正定&#xff0c;那可以用顺序主子式判断是否为半正定吗&#xff1f; 答案&#xff1a;不能 例子&#xff1a;A,特征值为一个0&#xff0c;两个正数>那就是半正定啦呀 但是&#xff0c;主子式二阶小于0那就不正定了呀两种方法…

线性代数【11】二次型

前言&#xff1a; 矩阵表达的是线性关系的方程组&#xff0c;但是&#xff0c;客官世界&#xff0c;是包括稍微复杂的&#xff0c;二次方程。 尤其几何中&#xff0c;有二次曲线&#xff0c;二次型&#xff0c;就是一个多元函数&#xff0c;是多个变量的二次&#xff0c;齐次…

Lyapunov稳定性分析1(正定函数、二次型正定判定)

一、 正定函数 1.1 定义&#xff1a; 令V(x)是向量x的标量函数&#xff0c;S是x空间包含原点的封闭有限区域。如果对于S中的所有x&#xff0c;都有&#xff1a; 则V(x)是正定的&#xff08;半正定&#xff09;。正定函数更直观的描述如下图所示&#xff1a; 如果条件(3&a…

牛顿法为什么要保证Hessian矩阵正定

牛顿法为什么要保证Hessian矩阵正定&#xff1a; 实际中&#xff0c;需要求出Hessian的逆矩阵&#xff0c;只有正定矩阵&#xff0c;才可以求出逆矩阵。 正定矩阵&#xff1a;特征值全大于0&#xff1b;各阶主子式全大于0.

正定矩阵的相关知识

一、正定矩阵的定义&#xff1a;若矩阵A是n阶方阵&#xff0c;并且它的二次型大于0&#xff0c;即 则矩阵A是正定矩阵。 二、正定矩阵的性质&#xff1a; 1.正定矩阵的所有特征值都为正数。 2.正定矩阵行列式为正数 3.两个正定矩阵的和为正定矩阵&#xff08;两个正定矩阵的乘…

顺序主子式的英文翻译(定义)

顺序主子式的英文翻译&#xff08;定义&#xff09; 为了查明顺序主子式的英文翻译&#xff0c;我在国内知网翻译助手、金山词霸等诸多翻译系统查了一下&#xff0c;给出的答案不外乎以下几个答案。 &#xff08;知网翻译助手的答案&#xff09; 我喜欢刨根问底&#xff0c;很明…

030 正定二次型及判别法之定义法、特征值法、顺序主子式法

030 正定二次型及判别法之定义法、特征值法、顺序主子式法

matlab-线性代数 det 各阶主子式、余子式、代数余子式

2019独角兽企业重金招聘Python工程师标准>>> matlab : R2018a 64bit     OS : Windows 10 x64typesetting : Markdown    blog : my.oschina.net/zhichengjiu    gitee : gitee.com/zhichengjiu 各阶主子式 code clear clca=[1 2 3;4 5 6;6 7 8…

主子式、顺序主子式、余子式、代数余子式

K阶子式 [ 1 ] ^{[1]} [1] (Minor) 以3阶行列式为例&#xff1a; ∣ a 1 a 2 a 3 b 1 b 2 b 3 c 1 c 2 c 3 ∣ \left| \begin{array} {ccc} a_1 & a_2 & a_3 \\ b_1 & b_2 & b_3\\ c_1 & c_2 & c_3 \end{array} \right| ∣∣∣∣∣∣​a1​b1​c1​​…

简单推导:关于矩阵主子式的几点性质

1.名词介绍: 特征多项式&#xff1a;在数域P上的某个方阵A,则行列式即为其特征多项式&#xff0c;简记为; 逆序数&#xff1a;1,2,...n的某个排序相对自然序列相反的个数&#xff1b;记为&#xff1a; 主子式&#xff1a;某个行列式的部分列和部分行&#xff1a;行号和列号一…

Zlib库的安装与使用

在实际应用中经常会遇到要压缩数据的问题&#xff0c;常见的压缩格式有zip和rar,而Linux下那就更多了,bz2,gz,xz什么的都有&#xff0c;单单Linux下的解压和压缩命令就有好多呢&#xff1f;没有什么好不好的。查了资料&#xff0c;应该是zlib这个比较简单好用。应用也广&#x…

zlib安装和使用 linux

zlib的安装与使用 zlib是一个很好的压缩解压缩库&#xff0c;今天我们分别介绍如何在Linux与Windows上安装与使用&#xff1a; 一&#xff1a;Linux平台 首先看看自己的机器上是不是已经安装好zlib了&#xff1a; whereis zlib 如果安装好了&#xff0c;会输出zlib的路径&…

zlib开发笔记(一):zlib库介绍、编译和工程模板

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://blog.csdn.net/qq21497936/article/details/111877005 长期持续带来更多项目与技术分享&#xff0c;咨询请加QQ:21497936、微信&#xff1a;yangsir198808 红胖子(红模仿)的博文大全&#x…