带*和?的KMP算法的两种实现方式

这两个都是我做助教的那个班的两个同学完成的,觉得她们做得不错,故贴出来共享。 第一个同学的实现:
#include
#include
#include
class String
{
private:
 char * str;
 int size;
public:
 String( char * s );
 ~String();
 
 
 int Strlen ( ) { return strlen( this -> str ) ; }                 //求长度
 char & operator [ ] ( int  i )  {  return  str [ i ] ; }             //重载下标运算符
};

String::String(char * s)
{
 size = strlen(s);
 str = new char[size + 1];
 assert(str != NULL);
 strcpy(str,s);
}
String::~String()
{
 delete str;
}
int * Nature(String & P)
{
 int len = P.Strlen() ;
 assert( len > 0 ) ;
 int * N = new int [ len ] ;
 assert( N != NULL ) ;
 if( P[0] == '*' )
  N[ 0 ] = -1 ;
 else
  N[ 0 ] = 0 ;
 int m = 0 ;
 int i = 1 ;
 while( m < len )
 {
  while( i < len && P[ i ] != '*')
  {
   int k = N[ i -1 ] ;
   if( P[ i ] == '?' || P[ k+m ] == '?')
    N[ i ] = k + 1 ;
   else
   {
    while( k > 0 && P[ i ] != P[ k+m ] && P[ k+m ] != '?')
     k = N[ k-1 ] ;
    if( P[ i ] == P[ k+m ] || P[ k+m ] == '?')
     N[ i ] = k + 1;
    else
     N[ i ] = 0;
   }
   i++;
  }
  while( P[ i ] == '*' )
  {
   N[ i ] = -1;
   i ++ ;
  }
  m =  i;
 }
 return N ;
}

int KMP( String & Target , String & Pat , int * N , int StartIndex )
{
 int i = 0 , count = 0 ;
 for( ; i < Pat.Strlen() ; i ++ )
  if( Pat[ i ] == '*' )
  count ++;
  int LastIndex = Target.Strlen() - Pat.Strlen() ;
 if( ( LastIndex - StartIndex ) + count < 0 )
  return ( -1 ) ;
 i = StartIndex ;
 int j = 0 ,m = 0 ;
 
 while( N[ j ] == -1 )
 {
  j ++;
  m ++;
 }
 int n ,k = 0;                   //n和k 用来记录开始匹配成功的位置
 while( i < Target.Strlen() )
 {
  while( Target[ i ] != Pat[ j ] && Pat[j ] != '?' && j > m )
   j = N[ j - 1 ] + m;
  if( Pat[j] == Target[i] || Pat[j ] == '?' )
  {  
   k++;
   if(k ==1 )
    n = i;

   j ++ ;
   m ++;
  }
   
  
  while( Pat[j] == '*')
  {
   j++;
   m++;
  }
  
  
  if( j == Pat.Strlen() )
  {
   cout<<"在位置 "<< n <<" 处匹配成功"<

第二个同学的实现:

class string
{
public:
 string();
    string(char *s);
 ~string();
 char* replace(char A, char B);
 int*  Next( string P);
 int KMP_FindPat(string S,string P,int* N,int startindex);
 bool print();
protected:
 int   size;
 char* str;
};

#include
#include
//#include
#include"String.h"
#include

string::string()
{
 size=0;
 str=NULL;
}

string::string(char* s)
{
 assert(s!=NULL);
 str=new char[strlen(s)+1];
 assert(str);
 strcpy(str,s);
 size=strlen(str);

}
//析构函数destructor
string::~string()
{
  size=0;
}

char* string:: replace(char A,char B)
{
 for(int i=0;i0);
 int* N=new int [m];
 N[0]=0;
 assert(N!=0);
 for(int i=1;i0 && P.str[j]!='*'&& P.str[j]!='?')
  {
    j=N[j-1];
  }
    if(  P.str[j]=='*')
  {
   j=j+1;
   while (S.str[i+1]!=P.str[j] && i
#include
void main()
{
 int *N;
 int n;
 //char* P="infinite";
 //char* S="infinishinfinfinite";
 string P("a*d*f");
    string S("sddddasdfhhhjf");
 P.print();
 S.print();
 N=P.Next(P);
    n=S.KMP_FindPat (S, P,N,0);
 cout<

posted on 2008-12-18 19:51  小橋流水  阅读(116)  评论(0编辑  收藏  举报

导航