带*和?的KMP算法的两种实现方式
2008-12-18 19:51
399 查看
这两个都是我做助教的那个班的两个同学完成的,觉得她们做得不错,故贴出来共享。
第一个同学的实现:
[code]
#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 <<" 处匹配成功"<
#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<
第一个同学的实现:
[code]
#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 <<" 处匹配成功"<
#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<
相关文章推荐
- 带*和?的KMP算法的两种实现方式
- Spring定时器的两种实现方式
- java实现文件下载的两种方式
- javascript中二分查找法的两种实现方式
- 多线程(三)--实现多线程的两种方式
- 单例模式的两种实现方式
- (二)跑马灯的两种实现方式
- TabHost两种实现方式
- Android实现资源动态加载的两种方式
- Java中有两种实现多线程的方式以及两种方式之间的区别
- Executor接口实现线程有返回值和无返回值两种方式
- Android 跑马灯效果实现的两种方式,解决和viewpager的冲突问题
- 两种方式实现多线程区别
- java内省的两种实现方式
- 两种方式实现压缩文件或文件夹
- 单例模式的两种实现方式
- APP夜间模式的两种实现方式
- spring实现定时任务的两种方式
- java实现MQ消息收发两种方式
- springMVC两种方式实现多文件上传及效率比较