题目链接
简单的KMP模板题
#include <iostream>
#include <stdio.h>
#include <string.h>
const int maxn = 1000000 + 10;
using namespace std;
int nexts[10000 + 10];
int n, m;
int a[maxn], b[10000 + 10];
void getNext(int *p,int next[]) { //优化后的求next数组的方法
int len = m;
next[0] = -1; //next 数组中的 最大长度值(前后缀的公共最大长度) 的第一个 赋值为 -1
int k = -1,j = 0;
while (j < len - 1) {
if (k == -1 || p[j] == p[k]) { //p[k]表示前缀 p[j] 表示后缀
k++; j++;
if(p[j] != p[k])next[j] = k;
else next[j] = next[k]; //因为不能出现p[j] = p[ next[j ]],所以当出现时需要继续递归,k = next[k] = next[next[k]]
}
else k = next[k];
}
}
int KMPSerach(int *s, int *p) {
int sLen = n;
int pLen = m;
int i = 0, j = 0;
while (i < sLen && j < pLen) {
if (j == -1 || s[i] == p[j])i++, j++;
else j = nexts[j];
}
if (j == pLen)return i - j;
else return -1;
}
int main() {
//freopen("in.txt", "r", stdin);
int T;
scanf("%d", &T);
while (T--) {
scanf("%d%d", &n, &m);
for(int i = 0; i < n; i++)scanf("%d", &a[i]);
for(int i = 0; i < m; i++)scanf("%d", &b[i]);
getNext(b,nexts);
int ans = KMPSerach(a, b);
if (ans != -1)printf("%d\n", ans + 1);
else printf("-1\n");
}
return 0;
}