#include<iostream>
using namespace std;
int a[1000005];
int b[10005];
int nextarr[10005];
int n, m;
//void getnext() //未优化
//{
// nextarr[0] = -1;
// int k = -1;
// int j = 0;
// while (j < m - 1)
// {
// //b[k]表示前缀,b[j]表示后缀
// if (k == -1 || b[j] == b[k])
// {
// j++;
// k++;
// nextarr[j] = k;
// }
// else
// {
// k = nextarr[k];
// }
// }
//}
void getnext() //优化后
{
nextarr[0] = -1;
int k = -1;
int j = 0;
while (j < m - 1)
{
//b[k]表示前缀,b[j]表示后缀
if (k == -1 || b[j] == b[k])
{
j++;
k++;
if (b[j] != b[k])
nextarr[j] = k;
else
nextarr[j] = nextarr[k];
}
else
{
k = nextarr[k];
}
}
}
int kmp(int a[], int b[])
{
getnext();
int i = 0;
int j = 0;
while (i < n && j < m)
{
//如果j=-1 或者当前匹配成功
if (j == -1 || a[i] == b[j])
{
i++;
j++;
}
else
{
//如果j != -1,且当前字符匹配失败,则令 i 不变,j = next[j]
//next[j]即为j所对应的next值
j = nextarr[j];
}
}
if (j == m)
return i-m+1;
else
return -1;
}
int main()
{
int t;
cin >> t;
while (t--)
{
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
cin >> n >> m;
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
for (int j = 0; j < m; j++)
{
cin >> b[j];
}
cout << kmp(a,b) << endl;
}
return 0;
}
hdu1711(kmp)
最新推荐文章于 2021-03-01 17:01:43 发布