KMP匹配算法,笔者在之前就有过研究,看了网上很多博客,但是还是懵懵懂懂,今天又拿起来重新研究,终于是搞懂了计算方法以及原理。
这里附上一篇很好的博客,笔者正是通过这个,懂得了next的计算。kmp的next数组值得求法
下面开始简单讲解一下:
模式串pattern=“abaabcac”——我们该如何求它的next数组呢?为了方便理解,我们数组下标从1开始。
相信你从网上其他很多资料对next数组已经有一定的了解了,那么我们直接上干货:
- 首先,我们规定:next[1]=0,next[2]=1。即next第一位为0,next第二位为1。
- 每次比较 设当前位为 i ,那么,我们通过比较 i-1 位上的字符与其 next[i-1] 对应的字符是否相等,如果相等,那么 next[i]=next[i-1]+1,即当前next的值加一。
- 如果与前一位相比较,发现不等,那么 我们继续向前寻找 即 i-1-1,重复上述2 步骤。但是请注意:我们比较的字符始终是i位置的前一个与我们寻找的不断向前的字符相比较(唔,好吧说的很拗口。看看例子)。
- 如果一直寻找到第一个位置上的字符,那么 i的next值就为1。
举个例子:
我们求模式串第四位 a的next,
先找到第三位的 a,和他的next[3],next[3]的值为1,那么就去模式串的 第一位字符(pattern.indexOf(next[3]-1))与 a 相比较(即a==?a),此时发现相等那么next[4]=next[3]+1。
我们假设不等于,
此时 我们将向前寻找,找到第二位的b,next[2]的值为1,那么此时就该比较 (注意这个a始终是第三位的,即第四位前面一位)a==?a(pattern.indexOf(next[2]-1)),
我们假设仍旧不等,那么继续向前,来到了第一位a,那么直接将next[4]的值赋为1即可。
next的求法就是这个,相信你多看几次就能够理解了。
下面是笔者的Java代码,可以参考一下:
Integer[] getNext(String pattern) {
Integer []next=new Integer[pattern.length()];//next数组与pattern长度相等
//初始化 next[0]=0,next[1]=1
next[0]=0;next[1]=1;
for(Integer i=2;i<next.length;i++) {
Integer pre=i-1;//前一位
Integer index=i-1;//可移动下标
while(true) {
if(index==0) {
next[i]=1;//当匹配到第一个时,next值为1
break;
}
if(pattern.charAt(pre)==pattern.charAt(next[index]-1)) {
//始终是找更前一位的next对应的值来与i的前一位相比较,匹配到了,那么i位置上的next值就是匹配上的next+1
next[i]=next[index]+1;//注意此处的赋值语句
break;
}
else {
index--;
}
}
}
return next;
}
关于next的使用就相对简单了,可以参考下面这篇博客:
kmp