扩展KMP学习

1.扩展KMP要解决的问题

   母串S,子串T,n = |S|,m = |T|, 

extend[i]表示S【i]与T最长公共前缀,要求在线性时间内求出extend[i]

 

2.算法分析

  1)暴力算法,时间复杂度O( n * n ),比较N次,每次长度从N到1

  2)扩展KMP, 时间复杂度O( n + m )

扩展KMP:

 

View Code
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<vector>
#include<string>
#include<math.h>
#include<map>
#include<set>
#include<algorithm>
using namespace std;

char S[1100], T[1100];
int next[1100];
int extend[1100];

//求next 函数
void get_next( )
{
   int i = 0, j = 1, k = 1, len = strlen(T);
   next[0] = 0;
   while( T[i] == T[i+k] )
          i++;
   next[1] = i;
   k = 1;
   for( int i = 2; i < len; i++)
   {
      if( i + next[i-k] < k + next[k] )
          next[i] = next[i-k];
      else
      {  
         j =  max(0, k + next[k] - i );
         while( T[j] == T[i + j] )
             j++;
         next[k = i] = j;    
      }         
   }
}

void Extend_KMP( )
{
  int i = 0, j = 1, k = 0, len = strlen(S);
  while( T[i] == S[i] )
     i++;
  extend[0] = i;
  k = 0;
  for( int i = 1; i < len; i++)
  {
    if( i + next[i - k] < k + extend[k] )
        extend[i] = next[i-k];
    else
    {
       j = max(0, k + extend[k] - i );
       while( T[j] == S[i + j] )
           j++;
       extend[k = i ] = j;    
    }     
       
  }
  
}
 
int main( )
{
  while( scanf("%s%s",S,T) != EOF )
  {
     get_next();
     for( int i = 0; i < strlen(T); i++)
       printf("%d ",next[i]);
     puts("");
     Extend_KMP( );
     for( int i = 0; i < strlen(S); i++)
       printf("%d ", extend[i]);
         
  }
  return 0;   
}

 

 

 

posted on 2012-08-07 22:20  more think, more gains  阅读(157)  评论(0编辑  收藏  举报

导航