带*和?的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<
本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名小橋流水(包含链接)。如您有任何疑问或者授权方面的协商,请给我发邮件。