位图介绍与实现
Posted 可乐不解渴
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了位图介绍与实现相关的知识,希望对你有一定的参考价值。
位图与布隆过滤器
位图的概念
位图的本质其实就是直接定值法的哈希,就是用每一个比特位来存放某种状态(通常用来表示该元素是否存在),由于表示每一个数据是否存在只需要使用一个比特位,其优点是节省空间,适用于海量数据,数据无重复的场景。
namespace ZJ
template<size_t N>
class BitSet//位图,解决不了字符串的情况
public:
BitSet();
void set(const size_t& val);//设置位
void reset(const size_t& val);取消位
bool test(const size_t& val)const;//检查该值是否在位图中存在
public:
std::vector<int> _bits; //按位存储的哈希表
;
位图的实现
构造函数
在我们使用位图时,首先要做的第一件事就是根据所需要N位数来创建N位的位图,并将所有的位图的所有位置都设置为0(即每一个位上表示的数据不存在)。
但是一个整形是有32个比特位的,因此用户输入N个位的位图就需要用到N/32个整形,但是实际我们所需要的整形个数是N/32+1,因为用户输入的位数可能小于1个整形所含盖的位数。
例如:当用户输入的位数是48位时,此时我们就需要创建两个整形(int),即需要 48 / 32 + 1 = 2,共计64个比特位。
BitSet()
_bits.resize(N / 32 + 1, 0);
set
set函数用于将某个值所映射的位置设置为存在状态,即对应的比特位设置为1。
设置x值对应到位图中指定的位的方法如下:
- 计算出该数(x)位于第 i 个整数的第 j 个比特位。
- 将1左移 j 位后与第 i 个整数进行或运算即可。
具体如下图所示:
// 把x映射的位标记成1
void set(size_t x)
assert(x < N);
// 算出x映射的位在第i个整数
// 算出x映射的位在这个整数的第j个位
size_t i = x / 32;
size_t j = x % 32;
// _bits[i] 的第j位标记成1,并且不影响他的其他位
_bits[i] |= (1 << j);
reset
set函数用于将某个值所映射的比特置为不存在状态,即置为0。
清空x值对应到位图中指定的位的方法如下:
- 计算出该值对应位图当中第 i 个整数的第 j 个比特位。
- 将1左移 j 位再取反后与第 i 个整数进行与运算即可。
具体如下图所示:
void reset(size_t x)
assert(x < N);
size_t i = x / 32;
size_t j = x % 32;
// _bits[i] 的第j位标记成0,并且不影响他的其他位
_bits[i] &= (~(1 << j));
test
tes函数用于获取x值对应的比特位的数据是否存在。
获取位图中x值对应指定的位的状态的方法如下:
- 计算出该位位于第 i 个整数的第 j 个比特位。
- 将1左移 j 位后与第 i 个整数进行与运算得出结果。
- 若结果非0,则该位对应的数据存在,否则该不存在。
bool test(size_t x)
assert(x < N);
size_t i = x / 32;
size_t j = x % 32;
// 如果第j位是1,结果是非0,非0就是真
// 如果第j为是0,结果是0,0就是假
return _bits[i] & (1 << j);
下期预告:C++11!!!
以上是关于位图介绍与实现的主要内容,如果未能解决你的问题,请参考以下文章