工作需要,自己封装了一个比特搜索类,都是静态函数。用KMP算法实现。
这是头文件:
//
BitSearch.h
#ifndef __CBITSEARCH__H
#define
__CBITSEARCH__H
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
class
CBitSearch
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
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 )
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
return ( T[pos>>3] & _fillmasks[pos%8] )?true:false;
}
}
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
#endif
这是实现文件:
//
BitSearch.cpp
#include
"
BitSearch.h
"
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
const
unsigned
char
CBitSearch::_fillmasks[]
=
...
{ 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
void
CBitSearch::GetNext(
const
unsigned
char
*
T,
int
len,
int
next[] )
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int j = 0, k = -1;
next[0] = -1;
while( j < len )
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
if( k == -1 || GetBit(T,j) == GetBit(T,k) )
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
++j; ++k;
if( GetBit(T,j) != GetBit(T,k) ) next[j] = k;
else next[j] = next[k];
}
else k = next[k];
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
//
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 )
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
if( start+tlen > slen ) return -1;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
int *next = new int[tlen+1];
if(!next) return -1;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
// Get the next value
GetNext(T, tlen, next);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
int i = start, j = 0;
while( i < slen && j < tlen )
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
if(j == -1 || GetBit(S,i) == GetBit(T,j)) ...{ ++i; ++j; }
else j = next[j];
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
delete[] next;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
if( j == tlen ) return i-j;
else return -1;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
//
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 )
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
if( start+tlen > slen ) return -1;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
int i = start, j = 0;
while( i < slen && j < tlen )
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
if(GetBit(S,i) == GetBit(T,j)) ...{ ++i; ++j; }
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
else ...{ i = i - j + 1; j = 0; }
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
if( j == tlen ) return i-j;
else return -1;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
//
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 )
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int count = 0;
int pos = 0;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
pos = IndexOfKMP( S, T, slen, tlen, start );
while( pos >= 0 )
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
pos = IndexOfKMP( S, T, slen, tlen, pos+tlen );
++count;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
return count;
}