KMP算法中的关键部分就是next数组,没有这个数组的维护,KMP算法根本没法实现。
下面来简单讲一下他的用途,这两天会持续更新:
1、求一个字符串中最长子串:(在保证这个字符串是由这些子串连续构成的情况下)
比如说一个子串:abcabcabc,目测最长子串长度为3。在求next数组的时候,每个字符的值依次为:-1, 0, 0, 0, 1, 2, 3, 4, 5, 6。这时候你会发现,明明字符串长度只有9啊,为什么我给出的next[i]会有10个数呢?第10个值,也就是6,是在字符串最后一个字符后面的假设的一个位置。也就是说,从第10个位置往前找,字符串前缀和后缀长度一致且相等的子串长度为6,,即abcabc。那么这个时候,最长子串的长度就是len - next[len]了,即3。在此不作证明,略去。
2、求一个字符串所有前缀字符和后缀字符匹配的长度:
说得有点绕,拿一个例子来说明:ababcababababcabab。在这个字符串中,符合要求的长度有2,4,9,18,即从最前往后K个字符与从最后往前K个字符一样。那你可能要说,在求next数组的过程中,我求出来的不是前缀字符和后缀字符匹配长度的最大值吗?现在要求所有值怎么求?很简单,想一下就可以发现,长度小的匹配一定是包含在长度大的匹配串中的,就拿上个例子,忽略自身18,最长长度是9:那么,在ababcabab中,是不是abab,ab也包括在里面?对啦,这其实是一个递归的思想,从大的匹配里可以找的更小的匹配。再考虑极端情况下:abcdefghijklmn,这14个字符里面,符合长度要求的就只有14了,递归已经到头了。每个子串长度的求法和第一种一样,就不赘述了。
在看完这些讲解后,做一些题体会一下吧。:)
练习题:POJ 2406, 2752