KMP匹配算法

以下是我自己写的关于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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值