关于KMP的总结
1.nextval数组
具体含义:
abcdefabc
在第二个c处匹配失败 则应将j匹配到c上 即为j = 2 = 最大部分匹配长度;
这里给出代码
void get_nextval()
{
nextval[0] == -1; //初变量不得为0 注意思考将j移到首位的命令与移动i的命令的区别
int i = 0; //为next赋值 因在下面循环中每次循环给next[i + 1]赋值 故初值为0
int j = -1;/* 当第一次循环或j追溯到next[0] 应有next[i] = 0 使其回到首位
而当Ti] = Tj]时 最大部分匹配子串长度加1;
此时发现若j初值为-1 上述三种情况代码可合并 于是有此初值*/
while(i < len - 1) //len为子串T长度
{
if(j == -1 || T[i] == T[j]
{
i++; //为i + 1赋值
j++;//子串长度+1 或是 为使j由-1到0;
if(T[j] == T[i])
nextval[[i] = nextval[j]; //①此语句放到下面讲解
else
nextval[i] = j;
}
else
j = nextval[j];/*若是T[j] != T[i] 则应试图寻找T[j] = T[i], 因nextval[j]早已求得
则若满足条件T[j]存在 应在一个T[j]前面有两个部分匹配子串
不好言述 可想象构图 有两个部分匹配子串 每个子串又有两个匹配子串 则有可能第一个子串跟第四个
子串匹配, 找寻第一个子串的方法便是回溯j;
若无法找到 最后应令j = -1以执行if语句 上述代码已满足 无需多言 */
}
}
关于①的解释:例如abcabcd 若匹配到第二个c匹配失败 按照旧版next求法 直接令nextval[i] = j, 则此时会继续匹配第一个c
而此时这个操作是百分之百无效的
于是在此进行改进 直接跳过此无效操作
此处改动更有效的针对aaaaaaaaab这种子串
②
关于KMP主函数
明确一点:KMP源代码寻找的是第一个匹配子串 有时须根据条件略微改动KMP
详见SDUT 3311;
小结:这只是数据结构初学者对于KMP的一些小心得
只是特别说明了一下自己之前困惑的地方
祝各位共同进步 ~
·