转自豆瓣大神总结,感觉这个讲得简单易懂,所以无耻的当个搬运工,谢谢大神总结
数据结构中,在串的这节,其实难度不大,关键是模式匹配的问题,而在模式匹配中要数KMP算法的难度最大,而KMP的next&nextval的计算则成了学习的重中之重。面对好多学校的教程跳过不讲,而教材里的公式又难以理解,好多自学的同仁们往往在这上面费尽心思。现在把我的学习心得发出来共享,如有错误,还望不吝指正。呵呵~
T : 1 2 3 4 5 6 7
串 : a b c a b a a
next : 0 1 1 1 2 3 2
nextval: 0 1 1 0 1 3 2
以上面的为例,先说next。next值本身的含义即是当进行匹配的模式串发生失配后,失配的这一字符再次进行匹配时要与哪个字符再进行比较?我们可以理解为这次配不上,那我下次和谁比?这样,next的值就与T发生了关系,表示了字符的比较位置。T就是元素的位置。
开始不用说,a前面没有,就是0,b要和a比,a的位置是1,b就是1。简单说,开头两个肯定是0,1!
第三个,c,c的前面是b,bc无法与开头的a比,所以c还是要单独找位于1的a,所以它也是1。
第四个,a,和第三个c一样,没有可以满足ca的字符串,最后a只能自己和第一个a配,它也是1。
第五个,b,看b前面,正好,a可以与开头的a对上,而第五个b正好在2的位置,所以b就是2。
第六个,a,看a前面,发现,a前面的ab可以与开头的ab对上,对上后,第六个a在位置3,所以就是3。
第七个,a,看a前面,只有a能够与开头配上,而“baa”则不行,所以它只有为2。
由此可以看出,next的计算,实际上就是计算当前字符以及当前字符前面的字符与开头匹配成功后,当前字符的最终位置,如果不成,就只能单独找第1个,所以它的值只能为1。
再看nextval,nextval是建立在next的基础上,我自己是这样理解的:同样是匹配,如果匹配成功,则位于后面的字符的next继承匹配成功的字符的nextval值,如果不成,保持不变。
以上为例:
第二位置的b按next值与开头a比较,不符,nextval不变,为1。
第三位置的c同样与1位置的a比较,不同,不变还是为1。
第四位置的a按next值与开头a比较,相同,继承开头a的nextval值,0。
第五位置的b按next值与二位置的b比较,相同,继承b的nextval值,1。
第六位置的a按next值与三位置c比较,不同,保持不变,3。
第七位置的a按next值与二位置b比较,不同,保持不变,2。
以上就是我的理解,当然,这是完全抛开了算法的描述,按照单纯计算next&nextval的值。关于算法,还是要好好理解的。
下面给出一个长的,加深印象。
123456789……
abcaabbabcabaacbacba
next: 01112231234532211211
nextval: 01102130110532210210