#include <iostream> #include <cstring> #include <cstdio> using namespace std; const int N = 1000100; int n, m; // n 主串长度, m模式串长度 int a[N], b[N]; // a 主串, b 模式串, 下标从零开始 int nextt[N]; void get_nextval() { int i = 0, j; j = nextt[0] = -1; while(i < m) { if(-1 == j || b[i] == b[j]) { ++i, ++j; nextt[i] = (b[i] != b[j]) ? j : nextt[j]; } else { j = nextt[j]; } } } int kmp_index(int pos) { // 求模式串在主串 pos位置 字符之后的位置 int i = pos, j = 0; while(i < n && j < m) { if(-1 == j || a[i] == b[j]) { ++i, ++j; } else { j = nextt[j]; } } if(j >= m) return i-m; else return -1; } int main() { int T; // freopen("D:\\in.txt","r",stdin); // freopen("D:\\out.txt","w",stdout); cin >> T; while(T--) { cin >> n >> m; for(int i=0; i<n; i++) { scanf("%d",&a[i]); } for(int i=0; i<m; i++) { scanf("%d",&b[i]); } get_nextval(); int temp = kmp_index(0);//0为查找下标 if(temp != -1)//找到的起始下标 ++ temp; cout << temp << endl; } // fclose(stdin); // fclose(stdout); return 0; }
从头到尾彻底理解KMP:https://blog.csdn.net/v_july_v/article/details/7041827
原文:https://www.cnblogs.com/Aiahtwo/p/10940180.html