HDU 1711Number Sequence(KMP)

好长时间没看模式匹配类型的题了,刚开始都不知道怎么写了,于是又仔细的看了一遍,才写出来.

题目大意:求出一个字符串在另一个字符串中的位子;

题目解析:运用模板算法KMP;

错误分析:数组不要开得太大;


#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#pragma comment(linker,"/STACK:102400000,102400000")
#define M 1000005
#define N 10005
int s[M],t[N],next1[N];//s[]表示主串,t[]模式串;
int n,m;
<span style="font-size:12px;">void next(int t[])        </span><span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px;"><span style="font-size: 10px;">//</span></span><span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px;">模式值数组next1表示:若主串与模式串到某个值时不相等,下一个j从何出开始比较;</span><span style="font-size:12px;">
</span><span style="font-size:12px;"><span style="font-size:10px;">
                                 </span></span>
{
    int i=1,j=0;
    next1[1]=0;
    while(i<m)
    {
        if(j==0||t[i]==t[j])
        {
            j++;i++;
            if(t[i]!=t[j])next1[i]=j;
            else next1[i]=next1[j];//相邻两个值不相等时,赋值为0;
        }
        else  j=next1[j];
    }
}
int KMP()//
{
    int i=1,j=1;
    while(i<=n&&j<=m)
    {
         if(j==0||s[i]==t[j])
        {
            i++;j++;
        }
        else j=next1[j];
    }
   if(j>m)return i-m;
   else return -1;

}
int main()
{
    int t1,i;
    scanf("%d\n",&t1);
    while(t1--)
    {
        memset(next1,0,sizeof(next1));//清零
        memset(s,0,sizeof(s));
        memset(t,0,sizeof(t));
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++)
        scanf("%d",&s[i]);
        for(i=1;i<=m;i++)
        scanf("%d",&t[i]);
        next(t);//把模式串传到函数中
        printf("%d\n",KMP());
    }
   return 0;
}


你可能感兴趣的:(KMP)