数据结构实验之串三:KMP应用
Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^
题目描述
有n个小朋友,每个小朋友手里有一些糖块,现在这些小朋友排成一排,编号是由1到n。现在给出m个数,能不能唯一的确定一对值l和r(l <= r),使得这m个数刚好是第l个小朋友到第r个小朋友手里的糖块数?
输入
首先输入一个整数n,代表有n个小朋友。(0<n<10000000)然后输入n个数,代表1到n个小朋友的糖块数。再输入一个整数m,然后输入m个整数。
输出
如果能唯一的确定一对l,r的值,那么输出这两个值,否则输出-1
示例输入
5 1 2 3 4 5 3 2 3 4
示例输出
2 4
提示
因为要判断唯一的一对,所以最多进行两次KMP匹配就行了。(因为数组比较大,只能定义为全局变量)。
#include<iostream>
#include<string.h>
using namespace std;
int p[10000000],s[10000000]; //7个0
int next[10000000];
void GetNext(int p[],int next[],int len)
{
int i=0,j=-1;
next[0]=-1;
while(i<len-1)
{
if(j==-1||p[i]==p[j])
next[++i]=++j; //next[++i]=j(直到满足if条件次后)+1;
else
j=next[j];
}
}
int KMP(int s[],int p[],int len1,int len2)
{
int i=0,j=0;
memset(next,0,sizeof(next));
GetNext(p,next,len2);
while(i<len1&&j<len2)
{
if(j==-1||s[i]==p[j])
{
i++;
j++;
}
else
j=next[j]; //i不变,j后退
}
if(j<len2)
return -1;
else return i-len2+1;
}
int main()
{
int n;
while(cin>>n)
{
for(int i=0; i<n; i++)
cin>>s[i];
int m;
cin>>m;
for(int i=0; i<m; i++)
cin>>p[i];
int i=KMP(s,p,n,m);
if(i!=-1)<span style="white-space:pre"> </span>//如果第一次匹配成功,进行二次匹配
{
int t=KMP(s+i,p,n,m);
if(t==-1)
cout<<i<<" "<<i+m-1<<endl;
else cout<<"-1\n";
}
else
cout<<"-1\n";
}
return 0;
}