如何改进kmp算法找到重叠结果

时间:2014-03-21 14:09:50

标签: c algorithm

这是我的源代码:

#include <stdio.h>
#include <string.h>
#include <malloc.h>

int *get_next(char *arr){
        int *next = (int *)malloc(sizeof(int) * strlen(arr));
        next[0] = -1;
        int i = 0;
        int j = -1;
        while( arr[i] != '\0' ){
                if( arr[i] == arr[j] || j == -1) {
                        i++;
                        j++;
                        next[i] = j;
                }else{
                        j = next[j];
                }
        }
        return next;
}
void kmp(char *arr, char *pat){
//      printf("in %s find %s ", arr, pat);
        int *next = get_next(arr);
        int i = 0;
        int j = -1;
        while( *(arr + i) != '\0'){
                if( j == -1 || arr[i] == pat[j] ){
                        j++;
                        i++;
                }else{
                        j = next[j];
                }

                if( j == strlen( pat )){
                        printf("at %d\n", i - j);

                }
        }
}
void main( void ){
        char test[] = "aabaaba";
        kmp(test, "aba");
}

我编译并运行它,没关系,但如果我用“aababa”更改测试

我只得到一个答案1;但答案是我们可以在第1和第3位找到aba

当两个结果重叠时发生此错误

任何人都有改进此算法的好主意吗?

1 个答案:

答案 0 :(得分:1)

void kmp(char *arr, char *pat){
    int found = 0, len1, len2, i = 0;
    char *temp = NULL;

    len1 = strlen(pat);
    len2 = strlen(arr);

    temp = calloc(len1 + 1, 1);
    if(temp == NULL){printf("Error in calloc \n"); exit(1);}

    for(i = 0; i < len2 - len1 + 1; i++){
        memmove(temp, &arr[i], len1);
        if( !strcmp(temp, pat) ){
            found = 1;
            printf("at position %d ", i);
        }
    }
    printf("\n");

    free(temp);

    if(!found){printf("No match! \n");}

    return;
}

瓦尔特