算法基础练习-KMP字符串实现----number sequence

题不知道哪个平台有,根据王道机试指南的题:
Given two sequences of numbers : a[1], a[2], … , a[N], and b[1], b[2], … , b[M] (1 <= M <= 10000, 1 <= N <= 1000000). Your task is to find a number K which make a[K] = b[1], a[K + 1] = b[2], … , a[K + M - 1] = b[M]. If there are more than one K exist, output the smallest one.


 - Input
   
   The first line of input is a number T which indicate the number of
   cases. Each case contains three lines.  The first line is two numbers
   N and M  (1 <= M <= 10000, 1 <= N <= 1000000).  The second line
   contains N integers which indicate  a[1], a[2], ...... , a[N].  The
   third line contains M integers which indicate b[1], b[2], ...... ,
   b[M].  All integers are in the range of [-1000000, 1000000].

 - Output
                 
        For each test case, 
        you should output one line which only contain K described above
        If no such K exists, output -1 instead. 
Sample Input

2 13 5 1 2 1 2 3 1 2 3 1 3 2 1 2 1 2 3 1 3 13 5 1 2 1 2 3 1 2 3 1 3 2 1 2 1 2 3 2 1 
Sample Output
6
-1

实现:

#include <cstdio>

//使用KMP进行字符匹配
const int MAXN=1000000;
const int MAXM=10000;

int nexttable[MAXM];
int parttern[MAXM];
int text[MAXN];

//创建next数组的函数,对模式串计算next
void getNext(int m){ //需要模式串的长度
    int j=0;
    nexttable[j]=-1;//初始化回溯标记
    int i=nexttable[j];
    while(j<m){         //对每位进行判断
        //i为-1的时候说明重新匹配需要递增
        if(i==-1||parttern[i]==parttern[j]){
            i++;
            j++;
            nexttable[j]=i;
        }
        else{
            i=nexttable[i];
        }
    }
}

//kmp的函数,返回匹配位置
int kmp(int n,int m){//n为主串长度,m为模式串长度
    getNext(m);
    int i=0,j=0;
    while(i<n&&j<m){
        if(j==-1||text[i]==parttern[j]){//j=-1即从头匹配
            i++;
            j++;
        }
        else{
            j=nexttable[j];
        }
    }
    if(j==m){//是否匹配成功
        return i-j+1;
    }
    else{
        return -1;
    }
}



//main函数,满足题意
int main(){
    int casenum;
    scanf("%d",&casenum);
    while(casenum--){
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++){
            scanf("%d",&text[i]);
        }
        for(int i=0;i<m;i++){
            scanf("%d",&parttern[i]);
        }
        int pos=kmp(n,m);
        printf("%d\n",pos);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值