1. 什么是Next数组?
传统的字符串匹配采用的是最简单的迭代,这必然会造成大量不必要的操作,Next数组的存在就是为了去除这些不必要的操作。
每一个Next数组的下标都映射了一个匹配串(AnalyzeThis)中具有相同下标的元素,当这个元素与主串(Text)的某个元素(设为a)不匹配的时候,
Next立功的时候就到了:
它会告诉这个电脑,应该继续从匹配串(AnalyzeThis)的哪个元素开始继续与a进行匹配工作。
2. Next数组的建立原理与数值意义
如前文所述,Next充当的是一个指挥着的角色。
这个是Next数组的定义:
(这是第一个元素) ||======================||=(这货就是传说中的第K个元素)===============....(1)
===============================||========================|| =(这个是第J个元素)============....(2)
如上面图所示,这两行表示的是同一串字符,为编译理解我将它表述为两行。其中第一行红色部分指代字符串P1 ...Pk-1
,第二行红色部分指代字符串Pj-k+1......Pj-1, 他俩相等。
相信看到这里大家都清楚了。因为Next[J]被使用的前提是,匹配串(Key)的J元素的前面所有元素都与主串某区域匹配,但主串的a元素与匹配串中K元素不匹配。
即等价于(2)的红色部分(字符串Pj-k+1......Pj-1)与主串相同区域匹配,即等价于(1)中的红色部分(字符串P1 ...Pk-1)
与主串的相同区域匹配,又因为这是一个最大的字串(参照上面的MAX定义),所以我只要继续比较匹配串中的K元素与主串中的a元素即可。
Next[J] = K 的原理如上所示~
KMP算法用伪代码描述如下:
1.在串S和串T中,分别设比较的起始下标i,j;
2.循环直到S中所剩余字符长度小于T中的长度或者T中所有字符均比较完毕
2.1如果s[i]=s[j],继续比较s和T的下一个字符;否则
2.2将j向右滑动到next[j]的位置,即j=next[j];
2.3如果j=0,则将i和j分别加1,准备下一趟比较
3.如果T中所有字符均比较完毕,则返回匹配的起始下标;否则返回0;