最近学到KMP算法,下面讲讲对KMP算法的一些个人理解,希望对大家有帮助!
对于KMP算法的理解:
整个KMP算法的流程可以这样看,首先对子串的自我匹配程度进行计算,算出的匹配程度分别记录下来称为next数组,然后开始用子串与母串进行匹配,如果一直匹配成功则不需要使用到next数组,当匹配到某一位出现失配时,用当前失配的位置作为下标到next数组中查找,用查找到的数计算出该把整个子串向后移动多少位(当前已匹配的子串长度 - 查找到的next数组对应的值+1),同时用查找到的数作为子串的下标开始匹配。
举个例子
例如有字符串
母串 S=“abceabceabca”
子串 T=“abceabca”
>第一步:计算出子串T的自我匹配程度是next = [0,1,1,1,1,2,3,4]
>第二步:开始匹配
a b c e a b c e a b c a
| | | | | | | \
a b c e a b c a
前面七个均匹配成功,到第八个 子串a-母串e 的时候匹配失败。
>第三步:查找next数组对应的第八位next[7]=4,当前已匹配长度为7,子串的向后移动位数为7-4+1=4,从T[4]开始匹配
a b c e a b c e a b c a
|
a b c e a b c a ->移动了四位
^
T串的第四位
next数组解决了朴素算法的两个问题
第一,已知子串自我匹配度为0,若子串与母串连续匹配即
S: a b c e a b
| | |
T: a b c
而又可知子串自我匹配度为0,T(a) != T(b) != T(c),所以T(a)不需要与S(b)、S(c)进行多余的匹配。
称为已知不相等的多余匹配
第二,已知子串有一定的自我匹配度,若子串与母串某一位匹配失败即
S: a b c e a b c e a b c a
| | | | | | | \
T: a b c e a b c a
而又可知子串T(abc1) = T(abc2),也就是有两串相同的字符串”abc”,子串的T(abc2)与母串的S(abc2)相匹配,所以T(abc1) = S(abc2),就不需要进行多余的匹配了。
称为已知相等的多余匹配
个人对于next数组的理解:
可以从两个方面理解next数组
1、记录子串失配后需要的后移位数(当前已匹配的子串长度 - 查找到的next数组对应的值+1)
2、记录子串需要回溯到自身哪个位置的下标
当然,1是为了便于理解以母串作为参考系的图形层面的说法,真正的计算机中并没有移动字符串这一说法,所以2才是next数组的真正意义
总而言之,next数组是记录子串匹配到哪一位出现失配的解决方案,它记录了失配后子串需要回溯到自身的哪一个位置。
以上