C++位图bitset的简单实现
1.引言

在计算机中,位图简单来说就是一串01序列,用每一位来存放某种状态。适用于海量数据、数据无重复的场景。通常都是用每一个位来判断在不在的一种模型。
具体使用场景包括但不限于:
1.快速查找某个数据是否在一个集合中
2. 排序 + 去重
3. 求两个集合的交集、并集等
4. 操作系统中磁盘块标记
5.给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。【腾讯】
2.实现思路
由于在实际代码中为了方便对位进行操作,我们选择底层使用vector包含一个字节的char的vector数组来具体移动位置。

需要实现的简单功能有:
1.set(size_t x) 将该位置bit位设置为1
2.reset(size_t x)将该位置bit位设置为0
3.test() //检测该位置是为0还是1
3.具体实现
3.1类结构
template<size_t N>
class BitSet
{
public:
BitSet() //构造
{
_bits.resize(N / 8 + 1, 0);//+1是为了防止65/8,多开一个,防止少一个没加的
}
void set(size_t x)//set是将bit位置为1
{}
void reset(size_t x)//reset是将bit位置为0
{}
bool test() //检测该位是0还是1
{}
private:
vector<char> _bits;
};
3.2set()
先通过除的方法找到具体是哪一个char,再通过取模的方法具体找到char中的哪一个bit位。
然后用当前值**或‘|’**上1之后左移的具体位数。
例如: 原本是: 1101 1001 我想让从右至左的第六位变成1,则‘|’ 0010 0000
那么应该是:
1101 1001
‘|’ 0010 0000
==> 1111 1001
void set(size_t x)//set是将bit位置为1
{
size_t i = x / 8; // 找到所在的char个数的位置
size_t j = x % 8; // 找到所在char的具体bit位
_bits[i] |= (1 << j); //左移 :1跟任何数|都是1
}
3.3reset()
通过除的方法找到具体是哪一个char,再通过取模的方法具体找到char中的哪一个bit位。
再用当前值**与‘&’**上1左移j位后的取反
例如: 1101 1001 想让从右至左第五位置成0,则与 0001 0000的取反 1110 1111取余
具体: 1101 1001
‘&’ 1110 1111
==> 1100 1001
void reset(size_t x)//reset是将bit位置为0
{
size_t i = x / 8;
size_t j = x % 8;
_bits[i] &= ~(1 << j);
}
3.4test()
检测该位到底是0还是1,则与1左移后的j位与‘&’
bool test() //检测该位是0还是1
{
size_t i = x / 8;
size_t j = x % 8;
return _bits[i] & (1 << j);
}
3.5测试
采用以下代码进行测试
void test()
{
BitSet<100> s; //将100bit中第10和11位置1
s.set(10);
s.set(11);
}
如上,若对一个100位大小的位图中,第10位和第11位进行置1,那么按照一个char一个字节8bit,应该是在第2个char中,且第二个char中的bit位应该是0011 0000。由于编译器无法看bit位,只能看16进制的数,那么对应的应该是00 0c 00 00让我们具体调试看看是不是这个值。

我们找到这个起始地址,再从监视窗口看。

是这个值,说明一个简单的bit位图就制作好了。
文章介绍了如何在C++中使用bitset数据结构来实现位图,包括通过vector存储、set()、reset()和test()函数的详细实现方法,适用于海量数据的快速查找、去重和集合运算等场景。
1022

被折叠的 条评论
为什么被折叠?



