KMP

#include <iostream>

using namespace std;

#define STR_SIZE 1024
#define PAR_SIZE 128

char str[STR_SIZE] = {"abaababaddecab"};
char par[PAR_SIZE] = {"abaabcaba"};

void printarray(int *a, int size);
int cal_k2(char *par, int *par_next, int k2, int j);
void cal_next(char *par, int *par_next, int par_len);
int kmp(char *str, char *par);
void printstep(char *str, char *par, int i, int j);

int main()
{
    int ret;

    ret = kmp(str, par);

//     int sz = 3;
//     int *p = new int(sz);
//     *(p+1) = 3;
//     cout<<*(p+1)<<endl;
// 
//     printarray(p, sz);
    if (ret <0)
    {
        cout<<"Mismatch!"<<endl;
    }
    else
    {
        cout<<"Match:"<<ret<<endl;
    }


    return 0;
}

void cal_next(char *par, int *par_next , int par_len)
{
    
    par_next[0] = -1;

    for (int i=1; i<par_len; i++)
    {
        int k = par_next[i-1];
        if (k==-1 )
        {
            par_next[i] = k+1;
        }
        else if(par[i-1] == par[k])   //计算第i个失配的时候
        {
            par_next[i] = k+1;
        }
        else
        {
            k = cal_k2(par, par_next, par_next[k], i-1);
            par_next[i] = k + 1;
        }
        cout<<i<<" ";
    }

}

int cal_k2(char *par, int *par_next, int k2, int j)
{
    int ret;
    if (k2 = -1)
    {
        return -1;
    }
    if (par[j]== par[k2])
    {
        ret = k2;
    }
    else
    {
        ret = cal_k2(par, par_next, par_next[k2], j);
    }

    return ret;
}



int kmp(char *str, char *par)
{
    if (!str || !par)
    {
        return -1;
    }
    
    int *par_next;
    int str_len, par_len;

    str_len = strlen(str);
    par_len = strlen(par);

    if (str_len==0 || par_len==0 || par_len> str_len)
    {
        return -1;
    }

    par_next = new int[par_len];

    if (!par_next)
    {
        return -1;
    }

    cal_next(par, par_next,par_len);
    cout<<"ParNext:"<<endl;
    printarray(par_next, par_len);

    int i=0,j=0;
    bool flag=false;

    while(i< str_len)
    {
        printstep(str, par, i, j);

        if (str[i]  ==  par[j])
        {
            if (j==par_len-1)
            {
                flag = true;
                break;
            }
            j++;
            i++;
        }
        else  //i位置失配
        {
            if (par_next[j] ==-1)
            {
                i++;
            }
            else
            {
                j = par_next[j];
            }
        }
    }

    delete[] par_next;
    par_next = NULL;

    return flag? i-par_len +1 : -1;

}

void printarray(int *a, int size)
{
    if (!a)
    {
        return;
    }
    for (int i=0; i<size; i++)
    {
        cout<<*(a+i)<<" ";
    }
    cout<<endl;
}

void printstep(char *str, char *par, int i, int j)
{

    if (!str || !par)
    {
        return;
    }
    for (int k=0;k<i ; k++)
    {
        cout<<" ";
    }
    cout<<""<<endl;
    cout<<str<<endl;
    for (k=0;k<i-j ; k++)
    {
        cout<<" ";
    }
    cout<<par<<endl;
    cout<<endl;
}
posted @ 2012-12-02 21:53  legendmaner  阅读(208)  评论(0编辑  收藏  举报