工作需要,自己封装了一个比特搜索类,都是静态函数。用KMP算法实现。
这是头文件:
//
BitSearch.h
#ifndef __CBITSEARCH__H
#define __CBITSEARCH__H
class CBitSearch
{
public:
static int IndexOfKMP( const unsigned char* S, const unsigned char* T, int slen, int tlen, int start = 0 );
static int IndexOf( const unsigned char* S, const unsigned char* T, int slen, int tlen, int start = 0 );
static int GetCount( const unsigned char *S, const unsigned char* T, int slen, int tlen, int start = 0 );
private:
static const unsigned char _fillmasks[];
static void GetNext( const unsigned char* T, int len, int next[] );
static inline bool GetBit( const unsigned char* T, int pos )
{
return ( T[pos>>3] & _fillmasks[pos%8] )?true:false;
}
} ;
#endif
#ifndef __CBITSEARCH__H
#define __CBITSEARCH__H
class CBitSearch
{
public:
static int IndexOfKMP( const unsigned char* S, const unsigned char* T, int slen, int tlen, int start = 0 );
static int IndexOf( const unsigned char* S, const unsigned char* T, int slen, int tlen, int start = 0 );
static int GetCount( const unsigned char *S, const unsigned char* T, int slen, int tlen, int start = 0 );
private:
static const unsigned char _fillmasks[];
static void GetNext( const unsigned char* T, int len, int next[] );
static inline bool GetBit( const unsigned char* T, int pos )
{
return ( T[pos>>3] & _fillmasks[pos%8] )?true:false;
}
} ;
#endif
这是实现文件:
//
BitSearch.cpp
#include " BitSearch.h "
const unsigned char CBitSearch::_fillmasks[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 } ;
void CBitSearch::GetNext( const unsigned char * T, int len, int next[] )
{
int j = 0, k = -1;
next[0] = -1;
while( j < len )
{
if( k == -1 || GetBit(T,j) == GetBit(T,k) )
{
++j; ++k;
if( GetBit(T,j) != GetBit(T,k) ) next[j] = k;
else next[j] = next[k];
}
else k = next[k];
}
}
// Search the sub bit stream using KMP
// Caller should ensure the input parameters are legal
int CBitSearch::IndexOfKMP( const unsigned char * S, const unsigned char * T, int slen, int tlen, int start )
{
if( start+tlen > slen ) return -1;
int *next = new int[tlen+1];
if(!next) return -1;
// Get the next value
GetNext(T, tlen, next);
int i = start, j = 0;
while( i < slen && j < tlen )
{
if(j == -1 || GetBit(S,i) == GetBit(T,j)) { ++i; ++j; }
else j = next[j];
}
delete[] next;
if( j == tlen ) return i-j;
else return -1;
}
// Caller should ensure the input parameters are legal
int CBitSearch::IndexOf( const unsigned char * S, const unsigned char * T, int slen, int tlen, int start )
{
if( start+tlen > slen ) return -1;
int i = start, j = 0;
while( i < slen && j < tlen )
{
if(GetBit(S,i) == GetBit(T,j)) { ++i; ++j; }
else { i = i - j + 1; j = 0; }
}
if( j == tlen ) return i-j;
else return -1;
}
// Get the times of sub bit stream appears in source bit stream
int CBitSearch::GetCount( const unsigned char * S, const unsigned char * T, int slen, int tlen, int start )
{
int count = 0;
int pos = 0;
pos = IndexOfKMP( S, T, slen, tlen, start );
while( pos >= 0 )
{
pos = IndexOfKMP( S, T, slen, tlen, pos+tlen );
++count;
}
return count;
}
#include " BitSearch.h "
const unsigned char CBitSearch::_fillmasks[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 } ;
void CBitSearch::GetNext( const unsigned char * T, int len, int next[] )
{
int j = 0, k = -1;
next[0] = -1;
while( j < len )
{
if( k == -1 || GetBit(T,j) == GetBit(T,k) )
{
++j; ++k;
if( GetBit(T,j) != GetBit(T,k) ) next[j] = k;
else next[j] = next[k];
}
else k = next[k];
}
}
// Search the sub bit stream using KMP
// Caller should ensure the input parameters are legal
int CBitSearch::IndexOfKMP( const unsigned char * S, const unsigned char * T, int slen, int tlen, int start )
{
if( start+tlen > slen ) return -1;
int *next = new int[tlen+1];
if(!next) return -1;
// Get the next value
GetNext(T, tlen, next);
int i = start, j = 0;
while( i < slen && j < tlen )
{
if(j == -1 || GetBit(S,i) == GetBit(T,j)) { ++i; ++j; }
else j = next[j];
}
delete[] next;
if( j == tlen ) return i-j;
else return -1;
}
// Caller should ensure the input parameters are legal
int CBitSearch::IndexOf( const unsigned char * S, const unsigned char * T, int slen, int tlen, int start )
{
if( start+tlen > slen ) return -1;
int i = start, j = 0;
while( i < slen && j < tlen )
{
if(GetBit(S,i) == GetBit(T,j)) { ++i; ++j; }
else { i = i - j + 1; j = 0; }
}
if( j == tlen ) return i-j;
else return -1;
}
// Get the times of sub bit stream appears in source bit stream
int CBitSearch::GetCount( const unsigned char * S, const unsigned char * T, int slen, int tlen, int start )
{
int count = 0;
int pos = 0;
pos = IndexOfKMP( S, T, slen, tlen, start );
while( pos >= 0 )
{
pos = IndexOfKMP( S, T, slen, tlen, pos+tlen );
++count;
}
return count;
}