题目描述:
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.
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
题意:
给出两个整形序列,判断第二个整形序列是不是第一个整形序列的子序列,如果是,那么请输出是从哪一个位置开始的子序列。
分析:
本题就是一个简单字符串匹配问题,不过将字符串改成了整形数。至于怎么输出是从哪一个位置开始的,其实很简单,我们在匹配成功时的i值是子序列的结束位置,那么子序列的长度又是可知的,直接用结束位置减去长度就是开始位置。
#include"stdio.h"
#include"string.h"
void Get_next(int text[],int next[],int m)
{
int i,j;
int len;
next[0]=-1;
i=0;
j=-1;
while(i<m)
{
if(j==-1||text[i]==text[j])
{
i++;
j++;
if(text[i]==text[j])
next[i]=next[j];
else
next[i]=j;
}
else
j=next[j];
}
}
int Index_KMP(int text[],int next[],int word[],int n,int m)
{
int i,j,k;
int lentext=n;
int lenword=m;
int count=1;
i=0;
j=0;
while(j<lenword&&i<lentext)
{
if(j==-1||text[i]==word[j])
{
i++;
j++;
}
else
{
j=next[j];
}
}
if(j==lenword)
return i-lenword+1;
return -1;
}
int text[1000001],word[1000001];
int next[1000001];
int main()
{
int i,j,count,T,m,n;
while(~scanf("%d",&T))
{
while(T--)
{
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
scanf("%d",&text[i]);
for(i=0;i<m;i++)
scanf("%d",&word[i]);
Get_next(word,next,m);
count=Index_KMP(text,next,word,n,m);
printf("%d\n",count);
}
}
}