#include<iostream>
#include<algorithm>
#include<stdio.h>
using namespace std;
const int maxn = 1e6+20;
int nxt[maxn];
int n,m;//n母串,m子串
int s[maxn];//母串
int t[maxn];//子串
void getnxt()//next数组
{
int i=1;
int j=0;
nxt[0]=0;
while(i<m)
{
if(t[j]==t[i])//情况1
{
nxt[i++]=++j;
}
else if(!j)//情况2 即j==0
{
i++;
}
else//情况3
{
j=nxt[j-1];
}
}
}
int kmp()
{
int i=0;
int j=0;
while(i<n&&j<m)
{
if(s[i]==t[j])
{
i++;
j++;
}
else if(j==0)
{
i++;
}
else
{
j=nxt[j-1];
}
}
if(j==m) return i-m+1;
else return -1;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d %d",&n,&m);
for(int i=0;i<n;i++) scanf("%d",&s[i]);
for(int i=0;i<m;i++) scanf("%d",&t[i]);
getnxt();
printf("%d\n",kmp());
}
return 0;
}
-------------------------
实例1.
nxt数组只与子串有关,储存的其实是最大公共前后缀
初始化
int i=1; int j=0;nxt[0]=0;
j=0 | i=1 | ||||||||
a | b | c | d | a | b | c | a | ||
t[0]=a | t[1]=b | t[2]=c | t[3]=d | t[4]=a | t[5]=b | t[6]=c | t[7]=a | ||
nxt[0]=0 | nxt[1] | nxt[2] | nxt[3] | nxt[4] | nxt[5] | nxt[6] | nxt[7] | ||
j=0 | i=1 | ||||||||
a | b | c | d | a | b | c | a | ||
t[0]=a | t[1]=b | t[2]=c | t[3]=d | t[4]=a | t[5]=b | t[6]=c | t[7]=a | ||
nxt[0]=0 | nxt[1]=0 | nxt[2] | nxt[3] | nxt[4] | nxt[5] | nxt[6] | nxt[7] | ||
j=0 | i=2 | ||||||||
a | b | c | d | a | b | c | a | ||
t[0]=a | t[1]=b | t[2]=c | t[3]=d | t[4]=a | t[5]=b | t[6]=c | t[7]=a | ||
nxt[0]=0 | nxt[1]=0 | nxt[2]=0 | nxt[3] | nxt[4] | nxt[5] | nxt[6] | nxt[7] | ||
j=0 | i=3 | ||||||||
a | b | c | d | a | b | c | a | ||
t[0]=a | t[1]=b | t[2]=c | t[3]=d | t[4]=a | t[5]=b | t[6]=c | t[7]=a | ||
nxt[0]=0 | nxt[1]=0 | nxt[2]=0 | nxt[3]=0 | nxt[4] | nxt[5] | nxt[6] | nxt[7] | ||
j=0 | i=4 | ||||||||
a | b | c | d | a | b | c | a | ||
t[0]=a | t[1]=b | t[2]=c | t[3]=d | t[4]=a | t[5]=b | t[6]=c | t[7]=a | ||
nxt[0]=0 | nxt[1]=0 | nxt[2]=0 | nxt[3]=0 | nxt[4]=j+1=1 | nxt[5] | nxt[6] | nxt[7] | ||
j=1 | i=5 | ||||||||
a | b | c | d | a | b | c | a | ||
t[0]=a | t[1]=b | t[2]=c | t[3]=d | t[4]=a | t[5]=b | t[6]=c | t[7]=a | ||
nxt[0]=0 | nxt[1]=0 | nxt[2]=0 | nxt[3]=0 | nxt[4]=1 | nxt[5]=j +1=2 | nxt[6] | nxt[7] | ||
j=2 | i=6 | ||||||||
a | b | c | d | a | b | c | a | ||
t[0]=a | t[1]=b | t[2]=c | t[3]=d | t[4]=a | t[5]=b | t[6]=c | t[7]=a | ||
nxt[0]=0 | nxt[1]=0 | nxt[2]=0 | nxt[3]=0 | nxt[4]=1 | nxt[5]=2 | nxt[6]=j+1=3 | nxt[7] | ||
j=3 | i=7 | ||||||||
a | b | c | d | a | b | c | a | ||
t[0]=a | t[1]=b | t[2]=c | t[3]=d | t[4]=a | t[5]=b | t[6]=c | t[7]=a | ||
nxt[0]=0 | nxt[1]=0 | nxt[2]=0 | nxt[3]=0 | nxt[4]=1 | nxt[5]=2 | nxt[6]=3 | nxt[7] | ||
j=0 | i=7 | ||||||||
a | b | c | d | a | b | c | a | ||
t[0]=a | t[1]=b | t[2]=c | t[3]=d | t[4]=a | t[5]=b | t[6]=c | t[7]=a | ||
nxt[0]=0 | nxt[1]=0 | nxt[2]=0 | nxt[3]=0 | nxt[4]=1 | nxt[5]=2 | nxt[6]=3 | nxt[7]=j+1=1 | ||
----------------------
实例2
j=0 | i=1 | ||||||||
a | a | b | a | a | b | a | a | a | |
t[0]=a | t[1]=a | t[2]=b | t[3]=a | t[4]=a | t[5]=b | t[6]=a | t[7]=a | t[8]=a | |
nxt[0]=0 | nxt[1] | nxt[2] | nxt[3] | nxt[4] | nxt[5] | nxt[6] | nxt[7] | nxt[8] | |
j=0 | i=1 | ||||||||
a | a | b | a | a | b | a | a | a | |
t[0]=a | t[1]=a | t[2]=b | t[3]=a | t[4]=a | t[5]=b | t[6]=a | t[7]=a | t[8]=a | |
nxt[0]=0 | nxt[1]=j+1=1 | nxt[2] | nxt[3] | nxt[4] | nxt[5] | nxt[6] | nxt[7] | nxt[8] | |
j=1 | i=2 | ||||||||
a | a | b | a | a | b | a | a | a | |
t[0]=a | t[1]=a | t[2]=b | t[3]=a | t[4]=a | t[5]=b | t[6]=a | t[7]=a | t[8]=a | |
nxt[0]=0 | nxt[1]=1 | nxt[2] | nxt[3] | nxt[4] | nxt[5] | nxt[6] | nxt[7] | nxt[8] | |
j=0 | i=2 | ||||||||
a | a | b | a | a | b | a | a | a | |
t[0]=a | t[1]=a | t[2]=b | t[3]=a | t[4]=a | t[5]=b | t[6]=a | t[7]=a | t[8]=a | |
nxt[0]=0 | nxt[1]=1 | nxt[2]=0 | nxt[3] | nxt[4] | nxt[5] | nxt[6] | nxt[7] | nxt[8] | |
j=0 | i=3 | ||||||||
a | a | b | a | a | b | a | a | a | |
t[0]=a | t[1]=a | t[2]=b | t[3]=a | t[4]=a | t[5]=b | t[6]=a | t[7]=a | t[8]=a | |
nxt[0]=0 | nxt[1]=1 | nxt[2]=0 | nxt[3]=1 | nxt[4] | nxt[5] | nxt[6] | nxt[7] | nxt[8] | |
j=1 | i=4 | ||||||||
a | a | b | a | a | b | a | a | a | |
t[0]=a | t[1]=a | t[2]=b | t[3]=a | t[4]=a | t[5]=b | t[6]=a | t[7]=a | t[8]=a | |
nxt[0]=0 | nxt[1]=1 | nxt[2]=0 | nxt[3]=1 | nxt[4]=2 | nxt[5] | nxt[6] | nxt[7] | nxt[8] | |
j=2 | i=5 | ||||||||
a | a | b | a | a | b | a | a | a | |
t[0]=a | t[1]=a | t[2]=b | t[3]=a | t[4]=a | t[5]=b | t[6]=a | t[7]=a | t[8]=a | |
nxt[0]=0 | nxt[1]=1 | nxt[2]=0 | nxt[3]=1 | nxt[4]=2 | nxt[5]=3 | nxt[6] | nxt[7] | nxt[8] | |
j=3 | i=6 | ||||||||
a | a | b | a | a | b | a | a | a | |
t[0]=a | t[1]=a | t[2]=b | t[3]=a | t[4]=a | t[5]=b | t[6]=a | t[7]=a | t[8]=a | |
nxt[0]=0 | nxt[1]=1 | nxt[2]=0 | nxt[3]=1 | nxt[4]=2 | nxt[5]=3 | nxt[6]=4 | nxt[7] | nxt[8] | |
j=4 | i=7 | ||||||||
a | a | b | a | a | b | a | a | a | |
t[0]=a | t[1]=a | t[2]=b | t[3]=a | t[4]=a | t[5]=b | t[6]=a | t[7]=a | t[8]=a | |
nxt[0]=0 | nxt[1]=1 | nxt[2]=0 | nxt[3]=1 | nxt[4]=2 | nxt[5]=3 | nxt[6]=4 | nxt[7]=5 | nxt[8] | |
j=5 | i=8 | ||||||||
a | a | b | a | a | b | a | a | a | |
t[0]=a | t[1]=a | t[2]=b | t[3]=a | t[4]=a | t[5]=b | t[6]=a | t[7]=a | t[8]=a | |
nxt[0]=0 | nxt[1]=1 | nxt[2]=0 | nxt[3]=1 | nxt[4]=2 | nxt[5]=3 | nxt[6]=4 | nxt[7]=5 | nxt[8] | |
j=2 | i=8 | ||||||||
a | a | b | a | a | b | a | a | a | |
t[0]=a | t[1]=a | t[2]=b | t[3]=a | t[4]=a | t[5]=b | t[6]=a | t[7]=a | t[8]=a | |
nxt[0]=0 | nxt[1]=1 | nxt[2]=0 | nxt[3]=1 | nxt[4]=2 | nxt[5]=3 | nxt[6]=4 | nxt[7]=5 | nxt[8] | |
j=1 | i=8 | ||||||||
a | a | b | a | a | b | a | a | a | |
t[0]=a | t[1]=a | t[2]=b | t[3]=a | t[4]=a | t[5]=b | t[6]=a | t[7]=a | t[8]=a | |
nxt[0]=0 | nxt[1]=1 | nxt[2]=0 | nxt[3]=1 | nxt[4]=2 | nxt[5]=3 | nxt[6]=4 | nxt[7]=5 | nxt[8]=2 | |
-----------
实例3.
a | b | x | a | b | c | a | b | c | a | b | y | |
a | b | c | a | b | y |
a | b | x | a | b | c | a | b | c | a | b | y | |
a | b | c | a | b | y |
a | b | x | a | b | c | a | b | c | a | b | y | |
a | b | c | a | b | y |
a | b | x | a | b | c | a | b | c | a | b | y | |
省略 | c | a | b | y |
|
--------------------------
实例3的符合代码的写法
母串 | a | b | x | a | b | c | a | b | c | a | b | y | |
↑ i=0 | |||||||||||||
j=0 ↓ | |||||||||||||
子串 | a | b | c | a | b | y | |||||||
nxt[i]= | 0 | 0 | 0 | 1 | 2 | 0 | 提前处理好nxt数组 | ||||||
由上表知 s[i]==t[j]=a;是情况一
所以i++; j++;执行后如下表
母串 | a | b | x | a | b | c | a | b | c | a | b | y | |
↑ i=1 | |||||||||||||
j=1 ↓ | |||||||||||||
子串 | a | b | c | a | b | y | |||||||
0 | 0 | 0 | 1 | 2 | 0 | 提前处理好nxt数组 | |||||||
由上表知s[i]==t[j]=b;是情况一
所以i++; j++;执行后如下表
母串 | a | b | x | a | b | c | a | b | c | a | b | y | |
↑ i=2 | |||||||||||||
j=2 ↓ | |||||||||||||
子串 | a | b | c | a | b | y | |||||||
0 | 0 | 0 | 1 | 2 | 0 | 提前处理好nxt数组 | |||||||
由上表知s[i]!=t[j]且j!=0;情况三
所以j=nxt[j-1]=nxt[1]=0;执行后如下表
母串 | a | b | x | a | b | c | a | b | c | a | b | y | |
↑ i=2 | |||||||||||||
j=0 ↓ | |||||||||||||
子串 | a | b | c | a | b | y | |||||||
0 | 0 | 0 | 1 | 2 | 0 | 提前处理好nxt数组 | |||||||
由上表知j==0;是情况二;
所以i++;执行后如下表
母串 | a | b | x | a | b | c | a | b | c | a | b | y | |
↑ i=3 | |||||||||||||
j=0 ↓ | |||||||||||||
子串 | a | b | c | a | b | y | |||||||
0 | 0 | 0 | 1 | 2 | 0 | 提前处理好nxt数组 | |||||||
接下来好几步都是 s[i]==t[j],是情况一 ;
所以i++; j++;执行后如下表
母串 | a | b | x | a | b | c | a | b | c | a | b | y | |
↑ i=4 | ↑ i=5 | ↑ i=6 | ↑ i=7 | ||||||||||
j=1 ↓ | j=2 ↓ | j=3 ↓ | j=4 ↓ | ||||||||||
子串 | a | b | c | a | b | y | |||||||
0 | 0 | 0 | 1 | 2 | 0 | 提前处理好nxt数组 | |||||||
直到不匹配出现
母串 | a | b | x | a | b | c | a | b | c | a | b | y | |
↑ i=8 | |||||||||||||
j=5 ↓ | |||||||||||||
子串 | a | b | c | a | b | y | |||||||
0 | 0 | 0 | 1 | 2 | 0 | 提前处理好nxt数组 | |||||||
由上表知s[i]!=t[j]且j!=0;情况三
所以j=nxt[j-1]=nxt[4]=2;执行后如下表
母串 | a | b | x | a | b | c | a | b | c | a | b | y | |
↑ i=8 | |||||||||||||
j=2 ↓ | |||||||||||||
子串 | a | b | c | a | b | y | |||||||
0 | 0 | 0 | 1 | 2 | 0 | 提前处理好nxt数组 | |||||||
由上表知s[i]==t[j];是情况一
所以i++; j++;执行后如下表
母串 | a | b | x | a | b | c | a | b | c | a | b | y | |
↑ i=9 | |||||||||||||
j=3 ↓ | |||||||||||||
子串 | a | b | c | a | b | y | |||||||
0 | 0 | 0 | 1 | 2 | 0 | 提前处理好nxt数组 | |||||||
由上表知s[i]==t[j],是情况一 ;
所以i++; j++;执行后如下表
母串 | a | b | x | a | b | c | a | b | c | a | b | y | |
↑ i=10 | |||||||||||||
j=4 ↓ | |||||||||||||
子串 | a | b | c | a | b | y | |||||||
0 | 0 | 0 | 1 | 2 | 0 | 提前处理好nxt数组 | |||||||
由上表知s[i]==t[j],是情况一 ;
所以i++; j++;执行后如下表
母串 | a | b | x | a | b | c | a | b | c | a | b | y | |
↑ i=11 | |||||||||||||
j=5 ↓ | |||||||||||||
子串 | a | b | c | a | b | y | |||||||
0 | 0 | 0 | 1 | 2 | 0 | 提前处理好nxt数组 | |||||||
-----------------------
实例4
a | b | c | x | a | b | c | d | a | b | x | a | b | c | d | a | b | c | d | a | b | c | y | ||||||||||
a | b | c | d | a | b | c | y |
a | b | c | x | a | b | c | d | a | b | x | a | b | c | d | a | b | c | d | a | b | c | y | ||||||||||
a | b | c | d | a | b | c | y |
a | b | c | x | a | b | c | d | a | b | x | a | b | c | d | a | b | c | d | a | b | c | y | ||||||||||
a | b | c | d | a | b | c | y |
a | b | c | x | a | b | c | d | a | b | x | a | b | c | d | a | b | c | d | a | b | c | y | ||||||||||
省略 | c | d | a | b | c | y |
a | b | c | x | a | b | c | d | a | b | x | a | b | c | d | a | b | c | d | a | b | c | y | ||||||||||
a | b | c | d | a | b | c | y |
a | b | c | x | a | b | c | d | a | b | x | a | b | c | d | a | b | c | d | a | b | c | y | ||||||||||
a | b | c | d | a | b | c | y |
a | b | c | x | a | b | c | d | a | b | x | a | b | c | d | a | b | c | d | a | b | c | y | ||||||||||
d | a | b | c | y |