#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 1070000;
int S[maxn];
int P[maxn];
int Next[maxn];
inline void BuildNext(int lenp)
{
int k = -1;
Next[0] = -1;//Next中存储的是这一位要移动到的下标,-1表示主要的串向后移动一位,匹配串放到第一位
for (int i = 0; i < lenp;)
{
//先处理上一位的事情
while (k > -1 && P[i] != P[k])//目前处理这一位的时候上一位的Next是已知的,同时k就是保存的上一位的next
{
k = Next[k];
}
i++;
k++;
if (P[i] == P[k])//如果两个位置相等,再向会找
{
Next[i] = Next[k];
}
else
{
Next[i] = k;
}
}
}
inline int kmp(int lenp, int lens)
{
int i = 0,j = 0;
while (i < lenp&&j < lens)
{
if (P[i] == S[j])
{
i++;
j++;
}
else
{
i = Next[i];
if (i == -1)
{
j++;
i = 0;
}
}
}
return (i >= lenp) ? j - lenp +1: -1;
}
int main()
{
int T;
cin >> T;
while (T--)
{
int lenp, lens;
cin >> lens >> lenp;
for (int i = 0; i < lens; i++)
{
scanf("%d", S + i);
}
for (int i = 0; i < lenp; i++)
{
scanf("%d", P + i);
}
BuildNext(lenp);
cout << kmp(lenp, lens) << endl;
}
return 0;
}
KMP算法
最新推荐文章于 2023-04-09 17:43:52 发布