给你两个串,问你第二个串是从第一个串的什么位置开始完全匹配的。。
思路:
裸的KMP,也是我的第一个KMP,说下对KMP的理解吧,首先对于非优化的方法求匹配,时间复杂度应该是O(n*m) ,而KMP则是O(n + m)(感觉会比这个长点,因为子串是不回溯,但是匹配串回溯了),但不管怎样,比以往的匹配快多了,KMP的关键就是处理匹配串,也就是给那个next数组赋值,得到next数组后,再根据next数组的特殊意思去简化时间复杂度,比如匹配串 1231234 当我们匹配到最后一个数的时候发现失配了,那么我们不用跳到第一个,而是直接跳到第四个位置上(数组从1开始)因为之前有一部分已经重复了而且是可以匹配的,所以我们就直接省事了,不用再去比较,这样子串也不用回溯到原先的起点+1然后在从新跑了,KMP给我的感觉就是记忆化的去匹配。
#include<stdio.h> int a[1100000]; int b[11000] ,next[11000]; void get_next(int m) { int j ,k; j = 0 ,k = -1; next[0] = -1; while(j < m) { if(k == -1 || b[j] == b[k]) next[++j] = ++k; else k = next[k]; } return ; } int KMP(int n ,int m) { int i ,j; j = 0; for(i = 0 ;i < n ;) { if(a[i] == b[j]) { if(j == m - 1) return i - (m - 1) + 1; i ++ ,j ++; } else { j = next[j]; if(j == -1) { i ++ ,j = 0; } } } return -1; } int main () { int t ,n ,m ,i; scanf("%d" ,&t); while(t--) { scanf("%d %d" ,&n ,&m); for(i = 0 ;i < n ;i ++) scanf("%d" ,&a[i]); for(i = 0 ;i < m ;i ++) scanf("%d" ,&b[i]); get_next(m); printf("%d " ,KMP(n ,m)); } return 0; }