KMP模式匹配算法保姆级详解

传统的朴素模式匹配算法

由于主串指针i回溯,且每次只前进一个距离,没有减少不必要的匹配过程。故效率非常低。

KMP算法

与朴素模式匹配算法不同,kmp巧妙的利用了当前c字符失配而c字符前面的字符都成功匹配
的信息,因此可跳过某些不必要的匹配。kmp将关注点落在了模式串t的有效信息提取上,与主串s
无关,故消除了主串s的回溯
1.kmp的重点就落在对模式串t的有效信息提取上即最长公共前后缀next数组

next数组是kmp算法的核心

next数组用以保存当前字符c之前子串的最长公共前后缀的信息
  • 手算next数组
    模式串t:g o o g l e
前缀集(不含最后字符) 后缀集(不含开始字符) 交集元素个数
g 空集 空集 0
go {g} {o} 0
goo {g,go} {o,oo} 0
goog {g,go,goo} {g,og,oog} 1
googl {g,go,goo,goog} {l,gl,ogl.oogl} 0
google {g,go,goo,goog,googl} {e,le,gle,ogle,oogle} 0
模式串t g o o g l e
next数组 0 0 0 1 0 0

利用next数组匹配
![在这里插入图片描述](https://img-blog.csdnimg.cn/6091d8af778a444db229e42a28316987.png
如上图当在字符 l 处发生匹配失败时,可知前面所有的字符已匹配成功。此时我们可能会想如果把模式串向右移使第一个字符g对齐匹配失败的前一个字符就好了。
没错这就是kmp算法的核心利用最长公共前后缀减少不必要的匹配过程

那么问题来了,将模式串向右移,移多少呢?这时候我们之前提到的提取有效信息next数组就发挥作用了。
我们需要将失配之前的最长公共前缀部分移动到后缀部分,也就是如下图这样。

![在这里插入图片描述](https://img-blog.csdnimg.cn/873f0340ef8c4df5aa56346517bdeac1.png

移动公式:
move = 指针j之前匹配成功个数 - next[j-1]  //将前缀移动到后缀处
	 = (j-1) - next[j-1]
	 
将比较指针j回退到
	j = j-move
	  = j - ((j-1)-next[j-1]) = next[j-1]+1

kmp模式串利用next数组匹配的核心 (j如何回退,回退到哪)

至此最重要的信息我们知道了,当字符c匹配失败后比较指针j回退到j = next[j-1]+1
即与失配指针j之前后缀字符相同的前缀后一个字符

也许我

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值