位图(bitmap),用每一位的bool值来表示存放的状态。0表示不存在,1表示存在。由于int 类型=4个字节,1 字节=8 bit,因此,采用bit位表示数据,空间性能提升了32倍。适用于大规模数据的表示,但数据状态不能太多,通常用来判断某一数据是否存在。
class Bitmap{ //位图Bitmap类
private:
char* M; int N; //比特图所存放的空间M[],容量为N*sizeof(char)*8比特 (举例,N=1时,容量为8bit)
protected:
void init( int n ) {
M = new char[N = ( n + 7 ) / 8];
memset( M, 0, N );
//memset函数用于对数组M中,N个位置置为0
//memset是计算机中C/C++语言初始化函数。作用是将某一块内存中的内容全部设置为指定的值
}
public:
Bitmap( int n = 8 ) { init( n ); } //按指定或默认规模创建比特图
~Bitmap() { delete [] M; M=NULL; } //析构时释放比特图空间
void set ( int k ) {
expand ( k );
M[k>>3] |= ( 0x80 >> ( k & 0x07 ) ); //k>>3 是通过移位操作确定对应的比特位所属字节的秩
}
void clear ( int k ) {
expand ( k );
M[k>>3] &= ~( 0x80 >> ( k & 0x07 ) );
}
bool test ( int k ) {
expand ( k );
return M[k>>3] & ( 0x80 >> ( k & 0x07 ) );
}
M[k>>3] |= ( 0x80 >> ( k & 0x07 ) ),其中:
k>>3 是通过移位操作确定对应的比特位所属字节的秩
k & 0x07 是用来确定该比特位在所属字节中的位置
假设k=18,18=2*8+2 可知,要将第三个字节的第二位状态变为1。
已知0x07的二进制是0000 0111后三位都是1,任何一个数字跟0x07与(&)操作,都能确定后三位的状态。
既然每一位能表示两种状态,后三位正好能表示8种状态。
首先,由k>>3 得出要变更的位置是M[2]。
由于数组M的下标从0开始,因此M[2]是第三个字节。 k & 0x07 =18&0x07=0001 0010&0000 01111,得到0000 0010=2
0x80>>2等价于0x80向右移动两位 0010 0000,M[2]=0000 0000 M[2]|=0010 0000
最终结果0010 0000 就将第三个字节的第二位变更1