https://blog.csdn.net/ArchyLi/article/details/78573362
位图BitMap:位图是一个数组,数组中的每一个数据元素的每一个二进制位表示一个数据,0表示数据不存在,1表示数据存在。
如上所示,当我们需要存放一个数据的时候,我们需要安装以下方法:
//定义每个Byte中有8个Bit位
#include <memory.h>
#define BYTESIZE 8
void SetBit(char *p, int posi)
{
for(int i=0; i < (posi/BYTESIZE); i++)
{
p++;
}
*p = *p|(0x01<<(posi%BYTESIZE));//将该Bit位赋值1
return;
}
void BitMapSortDemo()
{
//为了简单起见,我们不考虑负数
int num[] = {3,5,2,10,6,12,8,14,9};
//BufferLen这个值是根据待排序的数据中最大值确定的
//待排序中的最大值是14,因此只需要2个Bytes(16个Bit)
//就可以了。
const int BufferLen = 2;
char *pBuffer = new char[BufferLen];
//要将所有的Bit位置为0,否则结果不可预知。
memset(pBuffer,0,BufferLen);
for(int i=0;i<9;i++)
{
//首先将相应Bit位上置为1
SetBit(pBuffer,num[i]);
}
//输出排序结果
for(int i=0;i<BufferLen;i++)//每次处理一个字节(Byte)
{
for(int j=0;j<BYTESIZE;j++)//处理该字节中的每个Bit位
{
//判断该位上是否是1,进行输出,这里的判断比较笨。
//首先得到该第j位的掩码(0x01<<j),将内存区中的
//位和此掩码作与操作。最后判断掩码是否和处理后的
//结果相同
if((*pBuffer&(0x01<<j)) == (0x01<<j))
{
printf("%d ",i*BYTESIZE + j);
}
}
pBuffer++;
}
}
int main(int argc, _TCHAR* argv[])
{
BitMapSortDemo();
return 0;
}
参考:https://blog.csdn.net/ArchyLi/article/details/78573362
#include
#include
using namespace std;
class BitMap
{
public:
BitMap(size_t range)
{
//此时多开辟一个空间
_bits.resize(range / 32 + 1);
}
void Set(size_t x)
{
int index = x / 32;//确定哪个数据(区间)
int temp = x % 32;//确定哪个Bit位
_bits[index] |= (1 << temp);//位操作即可
}
void Reset(size_t x)
{
int index = x / 32;
int temp = x % 32;
_bits[index] &= ~(1 << temp);//取反
}
bool Test(size_t x)
{
int index = x / 32;
int temp = x % 32;
if (_bits[index]&(1<<temp))
return 1;
else
return 0;
}
private:
vector<int> _bits;
};
void TestBitMap()
{
BitMap am(-1);
BitMap bm(200);
bm.Set(136);
bm.Set(1);
cout << bm.Test(136) << endl;
bm.Reset(136);
cout << bm.Test(136) << endl;
}
int main()
{
TestBitMap();
return 0;
}
这里std::bitset使用
bitset就像一个bool类型的数组一样,但是有空间优化——bitset中的一个元素只占1 bit。
bitset有一个特性:整数类型和布尔数组都能转化成bitset。
在定义bitset时,要明确bitset含有多少位,须在尖括号内给出它的长度值:给出的长度值必须是常量表达式。
如果想用动态的bit数组,可以试试vector
但是不提倡使用vector< bool >,
因为它不是容器,不容纳bool类型,因为vector 打包 bool 以节省空间,每个保存在“vector”中的“bool”占用一个单独的bit。
同时禁止有指向单个比特的指针
vector c{ false, true, false, true, false };
bool *p = &c[0]; //错误,不能编译,因为无法将一个临时量地址给绑定到指针
关于bitset和vector
c++中bool数组与bitset,vector的使用与占用空间大小对比
在某些简单的情况下,不想自定义位图的实现时,也可以考虑下用vector
示例:
#include // std::cout
#include
using namespace std;
int main ()
{
vector<int> nums{0,-2,1,-3,9,42,10,4,34,33,6,13,5,-12,11,-8,57,15,74};
//先找出nums中的最大值和最小值
int minNums=INT_MAX,maxNums=INT_MIN;
for(auto &i:nums){
if(i<minNums) minNums=i;
if(i>maxNums) maxNums=i;
}
//将[minNums,maxNums]区间转换到[0,newMaxNums]
//将nums中每个元素减minNums即可实现
//注意bool是8 bits
//但是vector是vector的一个模板特化,内部会进行空间优化,保证bool类型在里面是1bit存储的。
vector<bool> temp(maxNums-minNums+1,false);
for(auto &i:nums){
temp[i-minNums]=true;//区间start前移到0
}
//看看temp的内存占用大小
//注意sizeof用于vector时,结果跟vector中的元素无关,只是返回这个vector<>类型的大小。
//cout<<"sizeof(temp)="<
//这里用temp.capacity()来输出vector类型的容量,单位为bit
cout<<"temp.capacity()="<<temp.capacity()<<"bits"<<endl;//此处的大小单位为bit
for(int i=0;i<temp.size();i++)
{
if(temp[i]==true)
cout<<i+minNums<<" ";//区间start恢复
}
system("pause");
return 0;
}