数据结构实验之串三:KMP应用

hanyujianke 2020-01-12

C - 数据结构实验之串三:KMP应用

Description

有n个小朋友,每个小朋友手里有一些糖块,现在这些小朋友排成一排,编号是由1到n。现在给出m个数,能不能唯一的确定一对值l和r(l <= r),使得这m个数刚好是第l个小朋友到第r个小朋友手里的糖块数?

Input

首先输入一个整数n,代表有n个小朋友。下一行输入n个数,分别代表每个小朋友手里糖的数量。

之后再输入一个整数m,代表下面有m个数。下一行输入这m个数。

Output

 如果能唯一的确定一对l,r的值,那么输出这两个值,否则输出-1

Sample

Input 

5
1 2 3 4 5
3
2 3 4

Output 

2 4
#include <bits/stdc++.h>

using namespace std;
int s1[1000100], s2[1000100];
int n1, n2, r;
int nexter[1000100];

void getnext(){                   //计算出nexter数组
    int k = -1, j = 0;
    nexter[0] = -1;
    while(j<n2-1){
        if(k == -1||s2[k] == s2[j]){
            k++, j++;
            if(s2[j]!=s2[k])        //避免s2[j] = s2[next[j]]的情况,节省时间
                nexter[j] = k;
            else nexter[j] = nexter[k];
        }
        else{
            k = nexter[k];
        }
    }
}

int fun(){
    int i = 0, j = 0, flag = 0;
    while(i<n1){
        if(s2[j] == s1[i]||j == -1){
            j++, i++;
        }
        else{
            j = nexter[j];
        }
        if(j == n2){
            r = i;                  //r为子串末尾对应的位数
            flag++;                 //统计条件中次数是否唯一
            if(flag == 1) r = i;
            j = 0;                  //s2返回到首字符,s1返回到已计数子串首字符的下一位开始查找
            i = i-n2+1;
            if(flag == 2) break;
        }
    }
    return flag;
}

int main()
{
        int i;
        scanf("%d", &n1);
        for(i = 0; i<n1; i++){
            scanf("%d", &s1[i]);
        }
        scanf("%d", &n2);
        for(i = 0; i<n2; i++){
            scanf("%d", &s2[i]);
        }
        getnext();
        int t = fun();
       if(t == 1) printf("%d %d\n", r-n2+1, r);
       else printf("-1\n");
    return 0;
}

相关推荐