工作需要,自己封装了一个比特搜索类,都是静态函数。用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
这是实现文件:
// 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;
}
