

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
int arr[] = {1,2,4,5,7,10,11,14,16,17,21,23,24,28,29,31};则我们只需要花1个字节来存这些数据

解释:我们目前很多的机器都是小端存储,也就是低地址存低位,一个整形数据中,第一个字节用来存储0-7的数字,第二个字节用来存储8-15的数字,第三个字节用来存储16-23的数字,第四个字节用来存储24-31的数字。我们来看看数字10是如何存储的。先通过模上32,取余还是10,然后再将4字节中第10个比特位置为1,则表示该数字出现过。由于我们的机器是小端存储,所以我们的每个比特位都是要从右边开始计算的,如下图

所以说我们只需要将对应的比特位置为1即可。但是如果我们要存储的数据很大呢?其实也很简单,我们可以定义一个数组,当做一个位图,如果该数字在0-31之间,我们就存储在0号下标的元素中进行操作,如果在32-63之间,则就在1号下标之间进行操作。计算下标我们可以通过模32来获得下标。
我们知道位图的原理后,我们在通过原理来用代码实现一个位图吧
实现
成员变量和构造函数:在实现位图中,我们的成员变量只需要一个数组就可以实现。而这个数组有多我们要开多大呢?数组多开一个整形空间,就能多存32个数字,所以我们可以让用户提供一个准确的数,这个数是一个数据量,也是数的最大范围。我们可以通过该数模上32,就可以获得该数组的大小,但是0~31模上32为0,我们开0个空间那显然不合适,所以我们要开range/32 + 1个空间大小的数组
存储数据:存储一个数字num需要3个步骤,第一是需要计算出该值对应的数组下标。计算数组下标方式为idx=num / 32;第二步是计算num在对应整数的比特位的位置bitIdx=num%32;第三步是要将计算出来的bite位置为1。我们之前说过,要操作位,我们可以通过位运算来操作,可以先将1左移bitIdx位后再和整数进行或运算
例如假设bitIdx=5,数据为10010011
1.将1进行左移5位==>100000
2.将数据和第一步计算出来的结果进行或运算
10010011 | 100000 =10110011,此时我们就将指定位置置位1了
查找数据:要判断一个数据是否存在,其实和存储数据是类似,也是需要计算出两个位置idx和bitIdx。然后通过这两个位置来判断对应位置是否为1,为1则表示该数字存在。如何判断呢?我们可以先将数组下标为idx的整数向右移bitIdx位,然后再和1进行与运算,如果为1则表示存在,否则不存在
例如假设bitIdx=5,数据为10110011
1.将数据进行右移5位00000101
2.将第一步计算出来的结果和1进行与运算
00000101 & 1 = 1,此时表示该数字存在,返回true
删除数据:删除数据和存储数据操作一样,唯一的区别就是将对应的bit位置为0。我们可以通过先将1进行左移bitIdx位,然后取反,将结果再和原来数据进行与运算
例如假设bitIdx=5,数据为10110011
1.将1进行左移5位后并取反011111
2.将第一步计算出来的结果和数据进行与运算
10110011 & 011111 = 10010011,删除成功
代码:
class BitMap
{
public:
//位图的内存大小和数据范围有关
BitMap(size\_t range)
:\_bit(range / 32 + 1)
{}
void set(const size\_t num)
{
//计算数组中的下标
int idx = num / 32;
//计算num在对应下标整数中的下标位置
int bitIdx = num % 32;
//将对应的比特位置1
_bit[idx] |= 1 << bitIdx;
}
bool find(const size\_t num)
{
int idx = num / 32;
int bitIdx = num % 32;
return (_bit[idx] >> bitIdx) & 1;


**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.youkuaiyun.com/topics/618668825)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

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



