KMP算法

字符串匹配,失败时回溯。。

void getNext(char needle[], int next[]);
int kmp(char needle[], char haystack[], int next[]);

int main()
{
    char needle[255] = {''};
    char haystack[255] = {''};
    int next[255] = {0};
    char el;
    int count = 1;
    
    printf("输入haystack字符串,以#结束:
");
    scanf("%c", &el);
    while(el != '#')
    {
        haystack[count] = el;
        count ++;
        scanf("%c", &el);
    }
    haystack[0] = count-1;
    
    getchar();
    
    printf("输入needle字符串,以#结束:
");
    scanf("%c", &el);
    count = 1;
    while(el != '#')
    {
        needle[count] = el;
        count ++;
        scanf("%c", &el);
    }
    needle[0] = count-1;
    
    getNext(needle, next);//生成next数组,next数组用于记录needle中每个字符匹配失败时将要回溯的位置。
    
    count = kmp(needle, haystack, next);
    if(count == 0)
    {
        printf("没找到
");
    }else {
        printf("找到了,位置为%d
", count);
    }
    return 0;
}

void getNext(char needle[], int next[])
{
    int i = 1, j = 1;
    next[1] = 0;
    next[2] = 1;
    j = 2;
    
    while( j<needle[0] )
    {
        if( i == 0 || needle[i] == needle[j] )
        {
            i++;
            j++;
            //next[j] = i;
            if(needle[i] == needle[j]) //用于避免【a a a a a】这样的needle在第三个a匹配失败时回溯到2,,,让其回溯到0
            {
                next[j] = next[i];
            }else {
                next[j] = i;
            }
        }else {
            i = next[i];
        }
    }
}

int kmp(char needle[], char haystack[], int next[])
{
    int i = 1, j = 1;
    
    while(i<=needle[0] && j<=haystack[0])
    {
        if( i==0 || needle[i] == haystack[j])
        {
            i++;
            j++;
        }else {
            i = next[i];
        }
    }
    
    if(i>needle[0])
    {
        return j-needle[0];
    }
    return 0;
}
原文地址:https://www.cnblogs.com/buerr/p/7395733.html