给定一个整数数组,最多100w个元素。再给一个特征数组,最多1w个元素。求特征数组在第一个数组中第一次出现的位置。如果没有出现,输出-1.
有多组数据。
kmp的模板题。
kmp有两种写法。第一种是求出nxt数组,nxt[i]表示当i失配时,则跳到nxt[i]的位置。注意设置nxt[0]=-1。
第二种是求出f数组。f[i]表示字符串S[0..i]的最长前后缀公共子串的长度。此时,注意设置f[0]=0。血的教训:将f[0]设成了-1,结果弄了好久。
其中nxt和f的关系(下标均从0开始) nxt[i]=f[i-1]。
比较而言,第一种写法更为简单。
#include<bits/stdc++.h> using namespace std; #define MAXN 1000005 int num1[MAXN],num2[MAXN],nxt[MAXN],f[MAXN],n,m,t; void getnxt() { nxt[0]=-1; for(int i=1;i<m;i++) { int j; for(j=nxt[i-1];j>=0&&num2[i-1]!=num2[j];j=nxt[j]); nxt[i]=j+1; } } int kmp() { for(int i=0,j=0;i<n;i++,j++) { while(j>=0&&num1[i]!=num2[j]) j=nxt[j]; if(j==m-1) return i-m+2; } return -1; } int main() { scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(int i=0;i<n;i++) scanf("%d",&num1[i]); for(int i=0;i<m;i++) scanf("%d",&num2[i]); getnxt(); printf("%d ",kmp()); } return 0; }