KMP匹配算法

来源:互联网 发布:for与to的用法区别知乎 编辑:程序博客网 时间:2024/06/13 05:17

以下是我自己写的关于KMP的一个模版题,这能有助于理解吧,这里用了next数组的升级版,不是原封的next数组;原封next数组我会贴在更下面:(代码我也写有注释)

#include <bits/stdc++.h>using namespace std;void get_nextval();int KMP(int pos);int nextval[255];char T[10],S[100];int main(){    int pos,ans;    printf("请输入S:\n");    scanf("%s",&S[1]);    getchar();    printf("请输入T:\n");    scanf("%s",&T[1]);    T[0]=strlen(T);    S[0]=strlen(S);    printf("请输入pos:\n");    scanf("%d",&pos);    ans=KMP(pos);    printf("%d\n",ans);    return 0;}void get_nextval()// 找next数组{    int i=1,j=0;    nextval[1]=0;//第一个都是0;    while(i<T[0])    {        if(j==0||T[i]==T[j])//如果发现前缀和后缀相同,就再比较下面一个字母;        {            i++;j++;            if(T[i]!=T[j])                nextval[i]=j;//            else                nextval[i]=nextval[j];        }        else            j=nextval[j];//这里就是前缀后缀不相同,直接赋值回溯;        //printf("333   %d\n",nextval[i]);这个输出是来测试里面每一个next的值得;    }}int KMP(int pos)//这里的pos是从主函数传过来的,表示主函数要求从pos之后开始匹配;{    int i=pos;//这个pos可以要也可以不要;    int j=1;    get_nextval();    while(i<=S[0]&&j<=T[0])//求得next数组后再来匹配T;    {        if(j==0 ||S[i]==T[i])        {            i++;j++;        }        else//匹配不成功就把j变化,j必须得回到前面去;        {            j=nextval[j];        }    }    if(j>T[10])        return i-T[0];//返回匹配成功的位置    else        return 0;}

原封next数组就是下面的代码,其他部分相同,就是求next数组那里改了而已,这里就和很多书上说的一样了。不过建议用上面一种;
只看next数组那一部分:

#include <bits/stdc++.h>using namespace std;void get_nextval();int KMP(int pos);int nextval[255];char T[10],S[100];int main(){    int pos,ans;    printf("请输入S:\n");    scanf("%s",&S[1]);    getchar();    printf("请输入T:\n");    scanf("%s",&T[1]);    T[0]=strlen(T);    S[0]=strlen(S);    printf("请输入pos:\n");    scanf("%d",&pos);    ans=KMP(pos);    printf("%d\n",ans);    return 0;}void get_nextval(){    int i=1,j=0;    nextval[1]=0;//第一个都是0;    while(i<T[0])    {        if(j==0||T[i]==T[j])//如果发现前缀和后缀相同,就再比较下面一个字母;        {            i++;j++;            if(T[i]!=T[j])                nextval[i]=j;//            else                nextval[i]=nextval[j];        }        else            j=nextval[j];//这里就是前缀后缀不相同,直接赋值回溯;        printf("333   %d\n",nextval[i]);    }}int KMP(int pos)//这里的pos是从主函数传过来的,表示主函数要求从pos之后开始匹配;{    int i=pos;    int j=1;    get_nextval();    while(i<=S[0]&&j<=T[0])//求得next数组后再来匹配T;    {        if(j==0 ||S[i]==T[i])        {            i++;j++;        }        else//匹配不成功就把j变化;        {            j=nextval[j];        }    }    if(j>T[10])        return i-T[0];//返回匹配成功的位置    else        return 0;}
0 0
原创粉丝点击