对于KMP在课件中的数据调整
KMP算法提供了一个高效的检索方法,但是由于其过于依赖数据的调用,所以如果数据的下标出现错误则不能正确的使用KMP算法。考虑到输入数组的时候,所有数据都是从“0”号位开始输入的,而课件中的KMP数据是从1开始计入的。所以部分内容需要你进行调整:
首先是next[j]部分:

假设一段字符串是aabcaaabcad,那么这段字符串的next[j]列表为:

关于索引部分,需要导入三个变量:首先是被匹配的主字符串(假设为S),第二个为匹配字符串(假设为T),第三个为从第几个字符串开始进行匹配。(假设为pos)
我们将KMP算法的索引部分函数称为index_KMP(char S[], char T[], int pos);
函数结构体如下:
int index_KMP(char S[], char T[], int next[], int pos){ int i = pos; //开始匹配的主字符串位置 int j = 0; //子字符串下标 while (i < strlen(S) && j < strlen(T)) { //开始进行检索。退出的条件是所判断的索引超出了个字的字符串长度。如果i超出意味着未找到。如果j超出意味着找到匹配的字符串 if (j == 0 || S[i] == T[j]) { i++; j++; } else{ j = next[j]; } } if (j == strlen(T)) { return (i - strlen(T); //返回的数值为从“x”位置开始匹配字符串(第一次匹配) } else{ return -1; //因为不存在从1号位开始计算,所以返回-1数值保证不与主字符串里面的索引造成冲突 } }
因为next数组是需要程序生成的。因为生成的next数组里面的各个数字都是程序生成,非人为输入,所以需要一个生成next数组的函数,这里面需要导入两个变量,其中一个为判断next数组的字符串,另一个是用来存储next数值的数组next[]
我们将生成next的函数称为get_next(char T[], int next[]);
函数结构如下:
void get_next(char T[], int next[]){ int j = 0; //postfix pointer, 指向字符串中最后位的字符 int k = -1; //prefix pointer, 指向字符串中最前位的字符 next[0] = -1; //默认情况下所有的第一个next数值都为-1(从0开始计算)或者位为0(从1开始计算) while (j < strlen(T)) { if (k == -1|| T[j] == T[k]) { j++; //移动末尾的指针 k++; //移动前面 next[j] = k; //考虑的是除判断位以前的所有字符,所以是next[j] = k; } else{ k = next[k]; //如果匹配失败,则退位到最近的重复位置的后一位字符。 } } }
关于会不会出现next[k]不存在的情况。因为产生的next数组都是用j进行一个个赋值的,而j又一直在k的前面,所以不会出现将一个不存在的next赋值给k的情况

浙公网安备 33010602011771号