数据结构实验之串三:KMP应用
Time Limit: 1000MS
Memory Limit: 65536KB
Problem Description
有n个小朋友,每个小朋友手里有一些糖块,现在这些小朋友排成一排,编号是由1到n。现在给出m个数,能不能唯一的确定一对值l和r(l <= r),使得这m个数刚好是第l个小朋友到第r个小朋友手里的糖块数?
Input
首先输入一个整数n,代表有n个小朋友。下一行输入n个数,分别代表每个小朋友手里糖的数量。
之后再输入一个整数m,代表下面有m个数。下一行输入这m个数。
Output
如果能唯一的确定一对l,r的值,那么输出这两个值,否则输出-1
Example Input
5 1 2 3 4 5 3 2 3 4
Example Output
2 4
Hint
Author
windream
PS:这道题一定要注意题目描述,唯一的,唯一的,唯一的l,r;出现重复就是-1,比如12121里面找121,就不行。它可能是1,3也可能是3,5;
#include<bits/stdc++.h>
using namespace std;
char str1[1001000];
char str2[1001000];
int next[1001010];
int ss;
int sss;
void Get_Next()
{
memset(next,0,sizeof(next));
int len = strlen(str2);
next[0] = -1;
int k = -1;
int j = 0;
while(j < len)
{
if(k == -1 || str2[k] == str2[j])
{
j++;
k++;
next[j] = k;
}
else
k = next[k];
}
}
void KMP(int x)
{
Get_Next();
int len = strlen(str1);
int lem = strlen(str2);
int i = x;
int j = 0;
while(i < len && j < lem)
{
if(j == -1 || str1[i] == str2[j])
{
i++;
j++;
}
else
j = next[j];
}
if(j >= lem)
{
ss = i-lem+1;//记录头位置
sss = i;//记录它的尾位置
}
else
ss = -1;
}
int main()
{
int n;
while(scanf("%d", &n) != EOF)
{
for(int i = 0; i < n; i++)
{
scanf("%s", &str1[i]);
}
int m;
scanf("%d", &m);
for(int i = 0; i < m; i++)
{
scanf("%s", &str2[i]);
}
KMP(0);
if(ss != -1)
{
KMP(ss);//从头位置,再一次做遍历
if(ss == -1)
{
printf("%d %d\n", sss-m+1, sss);
}
else
printf("-1\n");
}
else
printf("-1\n");
memset(str1,0,sizeof(str1));
memset(str2,0,sizeof(str2));
}
return 0;
}