KMP算法思路

KMP算法

前半(思路)

该算法主要用于解决两个字符串的匹配问题,例如:

字符串a:adcadcadcadde 字符串b:adcadde

我们需要找出串b在串a中所在位置的第一个下标,这里的结果就是 6

大部分人首先想到的应该就是暴力求解,使用两个变量aIndex1、bIndex2分别指向串a、串b,这种方法不会出错但是方法的事件复杂度比较高。3

KMP算法中会先生成一个next数组用于记录字符串b中子串的最长公共前后缀4,数组的长度为串b的长度,数组的作用就是当两个字符串比较出现不相等字符的情况时,可以不重新开始从串b的第一个字符开始比较,减少比较次数以及降低时间复杂度。

这里我先给出next数组5[-1, 0, 0, 0, 1, 2, 0]

使用next数组的总体思路和暴力算法类似只是当比较的字符不相同时,我们根据bIndex索引在next数组中对应位置的值,例如:

当bIndex等于5时发现字符不相同,这时我们在next数组中寻找next[5]的值2,然后再和串b中下标为2的字符进行比较,字符相等时就继续比较下一个元素,字符不相等时继续寻找next数组的值,直到值为-1,此时aIndex后移、bIndex恢复变为0.

下面我来讲讲具体的流程:

1、 首先aIndex、bIndex进行一一比较,相等进行第二步;否则进行第三步

2、index++、bIndex++,如果bIndex等于串b的长度6返回**(aIndex-b.length+1)**并结束流程,如果aIndex

3、根据bIndex寻找next[bIndex]对应的值并将其值设置给bIndex,如果值为-1,进行第四步;否则进行第一步

4、bIndex=0,进行第一步

KMP算法思路_第1张图片

如图aIndex、bIndex进行比较直到bIndex等于5时元素不相等,此时查看next[5]的值并将其赋值给bIndex

KMP算法思路_第2张图片

此时变为如上图所示的这种情况

aIndex、bIndex再次进行比较直到bIndex等于5时,又发现元素不相等,将next[5]的值赋值给bIndex

KMP算法思路_第3张图片

最后比较完成返回**(aIndex-b.length+1)**结果为:12-7+1=6

由于next数组中记录的是串b从0索引到当前索引下7的字符串的最长公共前后缀的长度,那么当出现元素不匹配情况时,如果串b前面的子串存在公共前后缀,那么公共前后缀的部分也就不需要再次进行比较,由于公共前后缀的长度为next[bIndex],那么bIndex就可以直接从索引为next[bIndex]的地方继续进行比较即可,也就是说bIndex不需要重新变为0,降低比较的次数。所以说当元素不相等时,如果next[bIndex]的值越大,比较的次数也就减少的越多。

KMP算法思路_第4张图片

直接将bIndex变为2继续进行比较

KMP算法思路_第5张图片

next数组的求解方法在另一篇文章


  1. 用于遍历串a ↩︎

  2. 用于遍历串b ↩︎

  3. 于是KMP算法出现 ↩︎

  4. 通常数组记录较短的字符串 ↩︎

  5. next数组的求法在最后 ↩︎

  6. 这时代表串b已经比较完 ↩︎

  7. 不包含当前索引 ↩︎

你可能感兴趣的:(算法,java,开发语言)