克努特-莫里斯-普拉特(KMP)算法;

#include <cstdio>
#include <cstring>
const int N = 101;
const int M = 51;
char a[N], b[M];
int lena, lenb, next[M], nextval[M];
void Get_next()    
{
    int i = 0, j = -1;
    next[i] = j;
    while(i < lenb)
    {
        if(j == -1 || b[i] == b[j])
        {
            i++; j++;
            next[i] = j;
        }
        else
        {
            j = next[j];
        }
    }
}
void Get_nextval()  //next[]的改进;
{
    int i = 0, j = -1;
    nextval[i] = j;
    while(i < lenb)
    {
        if(j == -1 || nextval[i] == nextval[j])
        {
            i++;
            j++;
            if(b[i] == b[j])
                nextval[i]=nextval[j];
            else
                nextval[i]=j;
        }
        else
            j=nextval[j];
    }
}
int index_KMP()    //适用于模式串与主串存在较多部分匹配情况下, 否则和朴素匹配差别不大, 但nextval[]数组 也是一种改进;
{
    int i = 0, j = 0;
    while(i < lena && j < lenb)
    {
        if(j == -1 || a[i] == b[j])
        {
            i++; j++;
            if(j == lenb)
                return i-j+1;
        }
        else
            j = next[j];
    }
}
void LXL()  // x^n 求n最大值
{
    if(lenb%(lenb-next[lenb])==0)
        printf("%d\n", lenb/(lenb-next[lenb]));
    else
        printf("1\n");
}
void FindPrefix-suffiLength() //既是前缀又是后缀 输出长度
{
    int num[N];
    Get_next();
    int k = 0;
    for(int i = lenb; i != 0)
    {
        num[k++] = next[i];
        i = next[i];
    }
    for(int j = k-2; j >= 0; j--)
        printf("%d\n", num[i]); 
    printf("%d\n", lenb);
}
int main(){
    while(scanf("%s%s", a, b))
    {
        lena = strlen(a);
        lenb = strlen(b);
        Get_next();
        Get_nextval();
     //   printf("1\n");
        for(int i = 0; i <= lenb; i++)
            printf(i==lenb?"%d\n":"%d ", next[i]);
        for(int i = 0; i <= lenb; i++)
            printf(i==lenb?"%d\n":"%d ", nextval[i]);
        int Q = index_KMP();
        printf("%d\n", Q);
        FindPrefix-suffiLength();
    }
    return 0;
}

 

posted on 2016-01-02 14:35  cleverbiger  阅读(205)  评论(0)    收藏  举报