对于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的情况

posted @ 2016-10-22 16:06  Lord_Age  阅读(224)  评论(0)    收藏  举报