昨天刚干完KMP算法,结果又出来了一个改进版???也是不得不感叹了,发明某种算法的人都是天才,因为现在我哪怕对着实现代码都要愁半天.......
KMP算法的改进在我看来主要是处理了模式串本身的字符相同情况,来使算法进一步提高效率。首先,先附上实现代码:
void get_nextval(string T, int* nextval)
{
int i, j;
i = 1;
j = 0;
nextval[1] = 0;
while (i < T[0])
{
if (j == 0 || T[i] == T[j])
{
++i;
++j;
if (T[i] != T[j])
nextval[i] = j;
else
nextval[i] = nextval[j];
}
else
j = nextval[j];
}
}
可以看到,对比之前的getnext算法,这段代码主要多出了这一段:
if (T[i] != T[j])
nextval[i] = j;
else
nextval[i] = nextval[j];
对于某模式串T=ABABAAABA,1<=j<=9
我们可以轻松的得到他的next数组为011234223
但是,打个比方说,若在j=3处发生了不匹配情况,即主串S中的字符不为A,按照next的逻辑,j指针将回溯到1,继续与S串进行比较,但是显然,j=1位置上依然是字符A,完全没有匹配成功的可能性。因此,j=1的比较步骤是多余的,应当直接进入j=0。
于是,在next的基础上,我们可以加入i位置与j位置上的字符是否相等的判断,若不相等,那么说同原先的getnext算法,因此将next[i]赋值为j。若是相等,那么即说明如果j位置上的字符与i位置上的字符肯定都不会与S串匹配,那么此处的i应该回溯到nextval[j]的位置,即第一个此类型的字符不匹配时的情况。
通过这种方法,成功减少了运算量,可喜可贺,可喜可贺!