KMP算法(个人从懵逼到理解过程详解)

KMP算法(个人从懵逼到理解过程详解)

首先要知道,KMP是解决字符串匹配问题的,是在暴力匹配的基础上进行优化。所谓暴力匹配,就是长串与短串之间挨个字符对比,当出现不匹配时,短串向后后移一位,再次从头匹配。而KMP算法,就是在对此进行优化:当出现不匹配时,是否可以多往后移动,从而减少不必要的比较过程。

说到KMP算法,网上各种大神,各种详解,上来先讲KMP是干嘛的,然后就直接讲怎么求next数组,然后当出现不匹配时,代入next数组,成功跳转。我:???

就我个人学习过程来说,最需要的是理解next数组是干嘛的,它到底做了什么?其实,next数组的意思就是,当某个位置出现不匹配时,应该跳转几步,比如next[0]的意思是,当第一个字符不匹配时,应该向后跳转几步,因为数组是从0开始的,所以,并不需要跳转,所以next[0]=0

下面举个例子:长串aaaaaaaaab,短串aaab
首先,我们要知道,next根据短串来分析,从头开始向后依次找出短串的最长相同前缀和后缀,比如短串aaab,第一个a前面没有东西,它是第一个,所以next[0]=0。第二个a,前面有一个a,它和本身重复,所以next[1]=1,第三个a,前面有两个a,所以next[2]=2,第四个数为b,b前面有三个a,所以最长前缀为3,所以next[3]=3,所以next数组的值依次为0123

上面只是讲一下next数组的求解过程,其实各种讲解中都会讲,说实话,不太容易理解,我想很多人有和我一样的疑问,为什么要用next数组保存前缀和后缀相同部分的长度?

好的,现在正式进入主题。我们来模拟一下匹配过程:
aaa aaaaaab
aaa b
当匹配到第四个位置时,出现匹配失败,因为数组是从0开始的,所以,其实是next[3]的位置出现匹配失败,查一下next数组,next[3]=3,意味着,此时,需要跳转了,把短串第一个a放到3的位置:
aaa aaaaaab
----- aaab
就是这样。这就是next数组的使用过程,我想大家肯定还有很多疑问,而且我猜你们的疑问和我当时学习时的疑问一样:
计算next数组是根据短串计算的,最后跳转也是短串,似乎和长串没什么关系,那为什么可以直接这样跳转?

☆好的,下面我来解答为什么可以这样跳转,最关键最关键的一点,就是:当出现匹配失败时,其实,默认的,匹配失败处,前面的都是成功匹配的,也就是说,失配点前面的短串和长串,是一模一样的
理解了这点,就容易理解next数组了,next数组记录的是什么?是短串每一个字符前面的内容,到底有多少前缀和后缀相同的。 而前面又说,匹配失败的点,前面的长串和短串是一样的,那不就代表着,短串的前缀和长串的后缀有多长是相同的? 所以,是不是可以直接把短串前缀和长串后缀相同的部分放在一起呢?即让短串向后跳转,让短串前缀相同的部分对照上长串后缀相同部分。 至此,KMP跳转完成了。

所以理解KMP算法,我个人的理解难点就是,匹配失败那个字符前面,默认是匹配成功的,这个默认很关键,所以既然匹配成功,所以前面的长串和短串就一模一样,所以直接根据最长前后缀跳转就OK啦。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页