KMP算法

KMP

KMP算法是一种改进的字符串匹配算法,
由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,
因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)

其实KMP算法就是在BF(暴力算法)上的一个优化,
以避免文本串当前匹配指针回溯的情况来提高时间效率。

实现过程:

在学习KMP算法前,需要理解一个KMP中的避免回溯的方法,NEXT数组。

首先摆出两个概念:
前缀:指的是字符串的子串中从原串最前面开始的子串,如abcdef的前缀有:a,ab,abc,abcd,abcde
后缀:指的是字符串的子串中在原串结尾处结尾的子串,如abcdef的后缀有:f,ef,def,cdef,bcdef

那next数组存的就是一个子串的前缀和后缀的最大交集,
简单来讲就是前缀和后缀的最长相同部分。

"A"的前缀和后缀都为空集,共有元素的长度为0"AB"的前缀为[A],后缀为[B],共有元素的长度为0"ABC"的前缀为[A, AB],后缀为[BC, C],共有元素的长度0"ABCD"的前缀为[A, AB, ABC],后缀为[BCD, CD, D],共有元素的长度为0"ABCDA"的前缀为[A, AB, ABC, ABCD],后缀为[BCDA, CDA, DA, A],共有元素为"A",长度为1"ABCDAB"的前缀为[A, AB, ABC, ABCD, ABCDA],后缀为[BCDAB, CDAB, DAB, AB, B],共有元素为"AB",长度为2"ABCDABD"的前缀为[A, AB, ABC, ABCD, ABCDA, ABCDAB],后缀为[BCDABD, CDABD, DABD, ABD, BD, D],共有元素的长度为0

在这里插入图片描述


接着讲讲在KMP匹配中NEXT的用法以便加深的它的理解。

当你求出了 next 数组之后,KMP 算法就很轻易搞定了,
下面我用三张图,让你明白 KMP 算法完成匹配的整个过程。
以目标串:s,指针为 i ;模式串:t 指针为 j ; 为例:
在这里插入图片描述
上图表示: “ s i − j “s_{i-j} sij ~ s i − 1 ” = = “ t 0 s_{i-1}” == “t_0 si1==t0 ~ t j − 1 ” , s i ! = t j ( 前 面 都 相 等 , 但 比 较 到 t j 时 发 现 不 相 等 了 ) 且 n e x t [ j ] = = k 。 t_{j-1}”,s_i != t_j(前面都相等,但比较到 t_j 时发现不相等了)且next[j] == k。 tj1si!=tjtjnext[j]==k
在这里插入图片描述
根据 next 数组的定义得知 “ t k t_k tk ~ t j − 1 ” = = “ t 0 t_{ j-1}” == “t_0 tj1==t0~ t k − 1 ” , 所 以 “ t 0   t k − 1 ” = = “ s i − k t_{k-1}”,所以 “t_0 ~ t_{k-1}” == “s_{i-k} tk1t0 tk1==sik ~ s i − 1 ” s_{i-1}” si1

在这里插入图片描述
将模式串右移,得到上图,这样就避免了目标穿的指针回溯。


现在讲讲Next数组的求法。

手工求法:

  1. 第一二位对应的next值分别为0和1
  2. 后面每一位的next值求解:根据前一位进行比较
    • 将前一位的字符 与前一位的next值作为下标对应的字符进行比较
    • 相等,则该位的next值就是前一位的next值加上1
    • 不等,向前继续寻找next值对应的内容来与前一位进行比较,直到找到某个位上内容的next值对应的内容与前一位相等为止,则这个位对应的值加上1即为需求的next值
    • 若找到第一位都不匹配,则改为的next值为1。
      在这里插入图片描述
  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值