当前位置:   article > 正文

关于KMP算法(多图详解)_kmp算法时间复杂度为什么是m+n

kmp算法时间复杂度为什么是m+n

为什么用KMP算法

KMP是一种高效的模式匹配的一种算法
模式匹配,说直白就是找寻子字符串在主字符串的位置

(其实KMP这三个字没啥意义,这算法是3个人研究出来的,取3人名字首字母也就是KMP)

暴利匹配算法

与KMP相对立的一个算法就是暴力匹配算法,逐个字符一一对比
形象地理解就是请添加图片描述
可以看到在这个简短的例子中,当主字符串(以下简称主串)对比到3时,与子字符串(简称子串)不同
那么就要折返到开始位置的下一位
如果主串再长点,对比的字符再离奇点(比如刚好和子串最后一位不同步)那么主串折返的次数会更多

假设主串长度为m,子串长度为n,那么主串要比对m-n+1个字符(除了最后那个长度比子串还短的都要比对)
最晦气的情况是刚好每次都是子串的最后一位不同步,那么每个主串字符都要比对n
最坏情况的时间复杂度将是O(m-n+1)n 即 O(mn-n2+n),实际情况是m远大于n,所以可以简写为O(mn)

KMP算法思路

暴力匹配算法最大的弊端就是要折返匹配
在这里插入图片描述
比如在上图这个例子中,明显看到在比对第4位的时候出现的不同步
暴力匹配就会重新从主串第2位开始与子串匹配
显然当前的前3位是同步的,如果错开一位必然不同步,造成浪费时间
但是
已经匹配前3位还是有信息可以用的,当前计算机已经知道了主串前3位的序列,我们直观感受的话,下一次匹配应该是把主串的第3位和子串的第1位开始匹配
在这里插入图片描述
而不必再去和主串第2位比,这个直观感觉的什么原理呢?
对于已经匹配的子串序列,可以取共同元素的下一位作为下一次匹配的起点
看不懂也没关系,请看下面分析

研究子串

(以下示例图,第一个数列是主串截取)
如果是第5位不同步
我们能直观感受到,第4位和第1位是相同元素,可以作为下次匹配的起点
在这里插入图片描述
如果是第4位不同步
可以看到,第3位于第1位有相同元素,可以作为下次匹配的起点
在这里插入图片描述

如果是第3位不同步,那没办法了,前两位都不同,逐一比较了
在这里插入图片描述
如果是第2位不同步,第一位相同没啥用……同上图

如果是第1位不同步,那肯定是没什么好折腾了,老老实实下一个数字比较吧

回顾刚才的思路,可以发现我们是在找寻当前位置之前的字符的共同点
再精确点,当前比对位置是j,前1~j-1个字符组成字符串s
找寻s的最长相等前后缀以实现对已经匹配好的字符的复用

前缀:包含第一个字符但不包含最后一个
后缀:包含最后一个字符但不包含第一个

比如这个子串在这里插入图片描述
当j=6时,1~5组成的字符串是abaab
最长相等前后缀就是ab,当第6位不同步时,直接跳转到第3位
在这里插入图片描述
这样,主串就不必返回到之前的状态,始终都是子串在自行调节对比位序

那么研究一下这个方案:找寻当前比对字符之前的字符,的最长相等前后缀

前方的字符串最长相等前后缀下一个比对位置
abaabab3
abaaa2
abaa2
ab1
a1

可以看到下一个比对位置是最长相等前后缀的长度+1
当比对第一个字符就不同步时,那么主串要向后移一格,我们就记为0,以示意主串后移
那么就得到这么一个数组
在这里插入图片描述

这就是KMP算法中的next数组,用于指示如果当前匹配失败,下次子串比对位置

流程图

在这里插入图片描述

最后一个判断语句,如果是no,那么意味着是i超出了主串长度
也就是这种情况在这里插入图片描述
主串后面无元素了,依然是匹配失败的情况

进一步优化

观察这个子串及其next数组
在这里插入图片描述
可以看到前4位都相同且为a
当第4位不匹配时
在这里插入图片描述
j应该等于next[4]即3
在这里插入图片描述
显然子串的4号位是a,与主串的4号位不同步,那么位于子串3号位的a也必然不同步
同理,当j=2时,也不同步,j继续指向1
那为什么不直接跳转到第一位呢?
所以,在构建好next数组后,还可以进一步优化

对于子串中的相同元素,取位序小的next值作为当前next值
以减少这种不必要的比对
那么新的next数组nextval应该变为
在这里插入图片描述

时间复杂度

主串长度为m,子串长度为n

暴利匹配算法时间复杂度是O(mn)
KMP算法时间复杂度为O(m+n),因为主串没有回退,子串也是近似没有回退
但在一般情况下暴力匹配算法执行时间也近似为O(m+n)毕竟我们寻找的子串大概率是一组无序的字符组成的,而不是有很多重复。
这也是为什么暴力匹配算法沿用至今。其实是懒
请添加图片描述

都看到这里了,留个赞再走呗。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/669198
推荐阅读
相关标签
  

闽ICP备14008679号