hdu1711 KMP入门 8-6xiaolver真菜

题意:输入两个数串,问第二个数串在第一个里面的位置,不存在返回-1;

KMP最难理解的我认为是下一个数组的求解只要稍微了解过就会知道KMP算法是匹配字符串失败时想办法跳过重复的匹配。;

1 2 3 1 2 4要匹配到1 2 3 1 2 3 1 2 3 1 2 4暴力就是一个一个枚举到结尾,但是你发现,这字符串匹配到第二个三时如果可以从子串中3开始就省下几次匹配。

NEXT数组求解

void getNEXT(char str2[])
{
NEXT[0]=-1;
int j=0;
int k=-1;
while(j<len2)
{
if(k==-1||str2[j]==str2[k]){j++;k++;NEXT[j]=k;}
else{k=NEXT[k];}

}
}

然后就是KMP的方法

int KMP()
{
getNEXT();
int i=0,j=0;
while(i<len1)
{
    if(j==-1||suzu1[i]==suzu2[j]){i++;j++;}
    else{j=NEXT[j];}
    if(j==len2)return i;
}
return -1;
}

最后贴一下辣鸡代码

#include <iostream>
#include <string>
#include <cstring>
#include <stdio.h>
#include <math.h>
#include <map>
#define sd(qwe) scanf("%d",&qwe)
#define ss(asd) scanf("%s",asd)
#define sc(xcv) scanf("%c",&xcv)
#define xh(ert,rty,tyu) for(int ert=rty;ert<=tyu;ert++)
#define fxh(u,i,o) for(int u=i;u>=o;u--)

using namespace std;
int len1,len2,suzu1[1000005],suzu2[10005],NEXT[10005];
void getNEXT()
{
    int j,k;
    j=0;k=-1;
    NEXT[0]=-1;
    while(j<len2)
    {
        if(k==-1||suzu2[k]==suzu2[j]){k++;j++;NEXT[j]=k;}
        else{k=NEXT[k];}
    }
}
int KMP()
{
    getNEXT();
    int i=0,j=0;
    while(i<len1)
    {
        if(j==-1||suzu1[i]==suzu2[j]){i++;j++;}
        else{j=NEXT[j];}
        if(j==len2)return i;
    }return -1;
}
int main()
{
    int k;sd(k);
    while(k--)
    {
        sd(len1);sd(len2);
        xh(i,0,len1-1)sd(suzu1[i]);
        xh(i,0,len2-1)sd(suzu2[i]);
        if(KMP()>-1)
            printf("%d\n",KMP()-len2+1);
        else
            printf("%d\n",-1);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_35557621/article/details/81449671