#学习笔记/数据结构与算法
KMP算法
(以下符号‘-’为格式分隔符,无意义)
主串指向序号用i表示,子串指向序号用j表示
KMP算法与暴力算法(BF算法,Brute Force)的区别在于,KMP算法中主串的i不回溯,也就是不回退,只移动j
移动j的方法就是设置一个函数,j的下一个位置=next( j )
假设 主串ABCABBABABABABCABA
子串ABCABA
—————————【i】
第一次匹配ABCAB【B】ABABABABCABA
———— —ABCAB【A】
—————————【j】
当子串比较到第6位,这时候不匹配了,停下,因为这个串很可能从起始点到某块H(不一定为一个点)前,然后块H后开始到第5(6-1,第6个前)个位置有前后相同的部分,这里称为H的前缀和后缀(这个例子中的前后缀是C前后的AB)
找相同的前后缀的时候,以最长的为准,所以当第6个位置不匹配停下时,前面5个是匹配的,因为这里面有相同的前后缀,所以可以跳过前面的前缀
因为前缀部分和子串的起始部分一样,然后子串可以移到后面和前缀相同的那部分(后缀)的位置继续匹配(后缀作为子串匹配的新起始部分),这时候位置i是不移动的,只移动j,把j移动到与前后缀相同部分之后的位置,与主串匹配剩下的内容
主串跳过的位数以及j的下一个位置(这两个值相同)我们用next( j )来计算
第一次匹配后,此时j=6,设下一个j的位置k=next( j ),找最长的前后缀,假设当前匹配失败的位置为k,那么最后一个匹配成功的位置也就是后缀的最后一位,就是k-1,这时候前缀的最后一位是2,所以k-1=2,得出k=3
关于next[j]的算法有很多解释,这里就不再赘述了,大家可自行查阅
也就是下一个j的位置为3,主串跳过3位
—————————【i】
第二次匹配ABCAB【B】ABABABABCABA
———————-AB【C】ABA
—————————【j】
之后不断重复该过程直到找到匹配位置或找不到退出