【给数学不好的人的KMP】字符匹配教程(一)next数组的理解
终于接触了一丁点字符匹配的东西(其实也只是入门的KMP),话说这个东西的确需要很强的数学思维,其中NEXT数组尤其坑爹,很多ACMER就是栽在了这个数组上,不明觉厉。什么诸如“失配” “数组移位”和一些S(i-1)...之类的一长串字母的确让我们十分不爽。更有博客表示这个确实很难,此中有真意,欲辨已忘言云云。。算法导论上的模板是从1开始的,自己还写了个SString数据类型让好多人云里雾里,今天我们就来试着解释一下KMP的基本原理吧。
字符匹配的基本问题是寻找子串在一长串中的位置。比如
一长串s:abacababt
子串t:abab,返回值就是4.当然你要非说5也行。。
寻找这种东西的位置,最先想到的思路自然是暴搜。。我们用i来表示大串中当前查找的位置,j表示子串中当前查找的位置,开始都是0,然后开搜,条件很简单,s[i]==t[j]。。。
原理见图,
代码如下:
这个数组可以使用搜索的方法得到。网上的教程质量参差不齐,这里给出一个能用的。下标从0开始,next[0]默认为0,获得的数组可以使用调试功能查看。
int next[1000];void build_next(string b){ int i,j=0,key=0; memset(next,0,sizeof(next)); for(i=1;i<b.size();i++) { j=next[i-1]; while(j==1 && b[i]!=b[j]) { j=next[j-1]; } if(b[j]==b[i]) { next[i]=j+1; } else next[i]=0; }}
这个数组的理解与否是掌握KMP的关键,具体怎么使用,下篇文章会给出更新。