KMP算法通俗易懂版

本文介绍了KMP算法,一种用于解决字符串匹配问题的有效方法。KMP算法通过使用部分匹配表(next数组)减少重复比较,提高效率。文章详细解释了部分匹配表的构建过程,以及如何利用该表在字符串不匹配时确定后移位数,从而避免了朴素模式匹配的回溯。此外,还提供了KMP算法的Java实现。
摘要由CSDN通过智能技术生成

KMP算法是由Donald Knuth、James H.Morris和于1977年联合发明的,用来处理字符串匹配问题。

【题目描述】:对给定两个字符串str和substr,如果字符串str中含有子串substr,则返回substr在str中的开始位置,不含有则返回-1。

在介绍KMP算法之前,我们先来看普通解法(朴素模式匹配)怎么做。
最普通的解法是从左到右遍历str的每一个字符,然后看如果以当前字符作为第一个字符出发是否匹配出 substr,这里从数组下标为0开始。假设 str=“bcabcababcbabcabba”,substr=“abcabb”。
1.substr第0位字符不匹配,说明从str[0]出发进行匹配是不行的,后移1位,从str[1]出发进行匹配

b c a b c a b a b c b a b c a b b a
a b c a b b

2.substr第0位字符不匹配,后移1位

b c a b c a b a b c b a b c a b b a
a b c a b b

3.substr第5位字符不匹配,后移1位

b c a b c a b a b c b a b c a b b a
a b c a b b

4.substr第0位字符不匹配,后移1位

b c a b c a b a b c b a b c a b b a
a b c a b b

如此循环,直到匹配成功

普通解法的时间复杂度较高,假设字符串str和substr长度分别为N和M,从每个字符出发时,匹配的代价都可能是O(M),一共有N个字符,所以整体的时间复杂度为O(N×M)。普通解法的时间复杂度这么高,是因为每次遍历到一个字符时,检查工作相当于从无开始,之前的遍历检查不能优化当前的遍历检查。

比如在第3步,我们已经知道"abcab"这5个字符是匹配的,而普通解法没有利用到这一事实,只是简单的将substr串后移;KMP算法思想就是利用这一事实,减少重复比较的次数,提高算法效率。

KMP算法是怎么实现的这一点呢?他在此使用了一个叫做 “部分匹配表” 的数据结构,如下图所示,这张表是怎样求得的在后面会讲到。

substr a b c a b b
部分匹配值 0 0 0 1 2 0

在进行到第3步时,采用KMP算法,利用部分匹配表计算substr向后移动的位数:
3.substr第5位字符’b’不匹配,查表得到部分匹配值为0,说明str当前不匹配的位置应该与substr的第0位字符进行下一次匹配,即substr向后移动5位(=已匹配串"abcab"长度5 - 查表得到的部分匹配值0)

b c a b c a b a b c b a b c a b b a
a b c a b b

4.substr第3位字符不匹配,查表得部分匹配值为1,substr向后移动2位(=已匹配串"abc"长度3 - 查表得到的部分匹配

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值