位图法存数据

8K字节的内存空间内,如何存unsigned short类型数据?

一般做法:

定义一个数组:unsigned short arrNormal[4096];

这样做,最多只能存4Kunsigned short数据。

 

利用位图法:

定义一个数组:unsigned char arrBit[8192];

这样做,能存8K*8=64Kunsigned short数据。

 

写数据元素:计算待写入数据在arrBit存放的字节位置和位位置(字节0~8191,位0~7

 

比如写1234,字节序:1234/8 = 154; 位序:1234 & 0b111 = 2,那么1234放在arrBit的下标154字节处,把该字节的2号位(0~7)置为1

      

字节位置:int nBytePos = 1234/8 = 154;

位位置:  int nBitPos = 1234 & 7 = 2;

 

//把数组的154字节的2位置为1

unsigned short val = 1<<nBitPos;

arrBit[nBytePos] = arrBit[nBytePos] | val;  //写入1234得到arrBit[154]=0b00000100

 

此时再写入1236

字节位置:int nBytePos = 1236/8 = 154;

位位置:  int nBitPos = 1236 & 7 = 4

 

.// /把数组的154字节的4位置为1

val = 1<<nBitPos;

arrBit[nBytePos] = arrBit[nBytePos] | val;  //再写入1236得到arrBit[154]=0b00010100

 

读数据元素:按位读取arrBit,取得位为1的字节位置和位位置。元素值为8* nBytePos + nBitPos

for (i=0; i<8192; i++)

{

       for (j=0; j<8; j++)

       {

              if (arrBit[i] & (1<<j))

              {

                     cout << "arrBit:" << i << " " << j << "    " << 8*i+j << endl;

              }

       }

}

会输出:

arrBit:154 2    1234

arrBit:154 4    1236


删除元素:计算待删除元素的字节位置和位位置:arrBit[nBytePos] &= ~(1<< nBitPos);

比如删除1234arrBit[154] &= ~(1<<2);

 

位图法的缺点:

1.可读性差

2.位图存储的元素个数虽然比一般做法多,但是存储的元素大小受限于存储空间的大小。

位图存储性质:存储的元素个数等于元素的最大值。

比如,1K字节内存,能存储8K个值大小上限为8K的元素。(元素值上限为8K,这个局限性很大!)

比如,要存储值为65535的数,就必须要65535/8=8K字节的内存。要就导致了位图法根本不适合存unsigned int类型的数(大约需要2^32/8=5亿字节的内存)。

3.位图对有符号类型数据的存储,需要2位来表示一个有符号元素。这会让位图能存储的元素个数,元素值大小上限减半。

       比如8K字节内存空间存储short类型数据只能存8K*4=32K个,元素值大小范围为-32K~32K

综上所诉:位图法的适用范围很特殊。

你可能感兴趣的:(存储)