hdu1711 KMP模板

题意:
     给你两个串,问你第二个串是从第一个串的什么位置开始完全匹配的。。


思路:

      裸的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;
}


原文地址:https://www.cnblogs.com/csnd/p/12063111.html