您的位置:首页 > 理论基础 > 数据结构算法

KMP模式匹配算法实现

2014-06-24 01:28 603 查看
/** \brief  KMP模式匹配

 *

 * \param

 * \param

 * \return

 *

 */

#include <stdio.h>

#include <stdlib.h>

/***************************************************

*如果START_INDEX为1,则表示:本程序中字符数组从1号元素开始存储字符,0号元素存储字符的长度

*如果START_INDEX为0,则表示:本程序中字符数组从0号元素开始存储字符,数组以'\0'结尾

***************************************************/

#define START_INDEX 0   //0 or 1

#if START_INDEX==0

#define CHAR_NUM 1000   //最大支持CHAR_NUM个字符

#endif // START_INDEX

#if START_INDEX==1

/***************************************************

*如果当前元素的前K个字符与模式串中最靠近当前元素 *

*的K个字符字串完全相同那么当前元素的next值就是K+1*

***************************************************/

int get_next(char *Tstring,int *next)

{

    int i=1,j=0;    //j指向字串中当前比对到的元素,其本质是下标

    next[1]=0;  //规定第一个元素的next值为0

    while(i<(Tstring[0]-0x30))

    {

        if(j==0||Tstring[i]==Tstring[j])  //如果当前的元素与上述注释中提到的字串后一个字符也匹配

        {

            next[++i]=j+1;//此时,上述注释中的字串元素个数K增加1,i加1(向后一个字符检索),而当前next值等于字串最后一个字符的next值加1

            j++;//字串向后一个字符检索

        }

        else    //如果不等

        {

            j=next[j];  //j指向字串中当前元素的next值指向的字符(字串的字串)

        }

        /*另一种写法

        if(j==0||Tstring[i]==Tstring[j])

        {

            j++;

            i++;

            next[i]=j;

        }

        else

            j=next[j];

        */

    }

}

/*********************************************

*先计算模式串的next数组

*如果比对成功则继续比较

*如果比对失败模式串则滑动到next[j]处继续

**与主串当前元素比较

*********************************************/

int KMP(char *s,char *t)

{

    int i=1,j=1;

    int *next=(int *)malloc((t[0]-0x30+1)*sizeof(int));

    get_next(t,next);

    puts("比对顺序依次为:\n");

    while(i<=s[0]&&j<=(t[0]-0x30))

    {

        if(j==0||s[i]==t[j])

        {

            printf("%d\t%d\n",i,j);

            i++;

            j++;

        }

        else

            j=next[j];

    }

    free(next);

    if(--j==(t[0]-0x30))

        return i-j;

    else

        return -1;

}

int main()

{

    int i,index;

    char *t="8ababdabc";

    char s[]={17,'d','v','h','v','b','a','b','a','b','d','a','b','c','a','s','x','z'};

    index=KMP(s,t);

    printf("\n%d\n",index);

    return 0;

}

#endif // START_INDEX

#if START_INDEX==0

int get_next(char *Tstring,int *next)

{

    int i=0,j=-1;

    next[0]=-1;

    while(Tstring[i]!='\0')

    {

        //if(j==-1||Tstring[i]==Tstring[j])

        if(j==-1)

        {

            i++;

            j++;

            next[i]=j;

        }

        else

        {

            if(Tstring[i]==Tstring[j])

            {

                i++;

                j++;

                next[i]=j;

            }

            else

                j=next[j];

        }

    }

    return 0;

}

int KMP(char *s,char *t)

{

    int i=0,j=0;

    int next[CHAR_NUM];

    get_next(t,next);

    /*int m=0;

    while(t[m]!='\0')

        printf("%d\t",next[m++]);*/

    puts("比对顺序:\n");

    while(s[i]!='\0')

    {

        if(j>=0&&t[j]=='\0')//next[0]=-1,所以j==-1的情况是存在的

            break;

        if(j==-1||s[i]==t[j])

        {

            i++;

            j++;

        printf("%d\t%d\n",i,j);

        }

        else

        {

            j=next[j];

            //printf("hello world!\n");

        }

    }

    if(t[j]=='\0')

        return i-j+1;

    return -1;

}

int main()

{

    int i,index;

    char *t="ababdabc";

    char s[]={'d','v','h','v','b','a','b','a','b','d','a','b','c','a','s','x','z','\0'};

    index=KMP(s,t);

    printf("\n%d\n",index);

    return 0;

}

#endif // START_INDEX
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C 数据结构