KMP字符串匹配算法中部分匹配值的高效计算方法

最近看了KMP算法,算法很巧妙,但觉得讲解中的用前缀后缀法求部分匹配值效率有些低,在网上搜索一下,发现讲解的都是前缀后缀方法,经过我冥思苦想,想出了一个更高效的方法,在这里分享一下。

看本文前需先了解KMP算法,关于KMP的完整算法,这个讲得很不错http://www.ruanyifeng.com/blog/2013/05/Knuth–Morris–Pratt_algorithm.html
这里就不再赘述。

部分匹配值本质是字符串最后一段与字符串开头最多能有多少个连续字符相同(原因从上述教程的图中不难看出),所以只要从第二个字符开始与前面整个字符串进行对比,判断到当前字符前有多少个相同字符即可。


方法过程: 以上述教程中的用例“ABCDABD”为例子,

第一个字符的部分匹配值永远都是0,第二个字符B!=A,字符匹配值也为0;
在这里插入图片描述

下面的字符串后移,比较第3个字符C!=A,部分匹配值为0,同理第4个字符也为0,直到第5个字符A==A,部分匹配值为到此为止从第一个字符开始连续相同的字符数1;
在这里插入图片描述

相同不需要移动,继续比较下一个字符B==B,第6个字符的部分匹配值为2;
在这里插入图片描述

继续对比,第7个字符D!=C,出现不同不代表前面一部分子串也不相同,一般做法是下面的字符串后移一位,再从第7个字符向前对比,直到第一个字符都相同才能确定部分匹配值,但一位一位移效率太低,KMP算法也正是通过部分匹配值判断直接移多少位可以得到字符串完全重合的结果,所以这里也使用KMP的这个思想,对于下面一个字符串,字符C前面一个字符B对应的部分匹配值是0(注意:下面的字符中B是第二个字符,而不是上面的第6个字符,使用部分匹配值的都是要移动的字符串的),

在这里插入图片描述

所以后移 [相同子串长度2]-[部分匹配值0]=2个字符;移动后继续对比上面第7个字符D!=A,仍不相同,但已经是下面第一个字符,无法再移,部分匹配值为0;
在这里插入图片描述

最后得出部

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值