当前位置:网站首页>位图的基本原理以及应用
位图的基本原理以及应用
2022-08-09 22:13:00 【HHYX.】
位图的应用场景
假设生活中有以下这种应用场景:有未排序的40亿个数,需要在其中查找一个数字是否存在。如果直接使用数组来存放这些数,那么一个整型的数占4个字节,40亿个数需要16G的内存大小,从空间上来说一般很难实现,更不用说如果要进行排序产生的损耗等问题了。那有没有什么好方法来存放这么大量的数据呢?这种时候可以用到位图。
位图的基本概念
所谓位图,就是用每一位来存放某种状态。一个字节有8位,那么每一位都可以用来存放某个数字是否存在。一般单个位图虽然适用于海量数据,但是遇到重复数据只能记录一次存在,不过如果使用多个位图也可以解决数据出现次数问题。下面来看看位图具体是怎么做的
位图
这里是C++库里面对位图的介绍,那么为了更深刻的理解位图,可以自己来简单实现一下。实现代码如下:这里需要注意的是数组里面存放的是char占一个字节,也就是8位,用来表示状态的话相当于可以存放8个数据,因此在开空间的时候,将需要的数据大小除以8,这样一来原本需要16G左右的数据现在仅需要0.5M即可(原来数据是用int保存int占4个字节)。为了开足够的空间,这里在除以8之后再加上1。
后面简单实现的3种功能:设置和取消设置某个数的状态以及判断一个数是否存在。
这里的关键点在于需要确定某个数应当存放的vector数组的下标,用该数与8取模即可得到。然后该数存放的比特位位置,使用该数除8也可以得到,然后使用位运算符进行计算即可。
template<size_t N>
class bitset
{
public:
bitset()
{
_bits.resize(N / 8 + 1, 0);
}
void Set(size_t x)//设置为1
{
size_t i = x / 8;//确定该数字存储位置
size_t j = x % 8;//确定该数字存在该char类型的第几个位
_bits[i] |= (1 << j);
}
void Reset(size_t x)//设置为0
{
size_t i = x / 8;//确定该数字存储位置
size_t j = x % 8;//确定该数字存在该char类型的第几个位
_bits[i] &= (~(1 << j));
}
bool test(size_t x)//判断是否存在
{
size_t i = x / 8;//确定该数字存储位置
size_t j = x % 8;//确定该数字存在该char类型的第几个位
return _bits[i] & (1 << j);
}
private:
vector<char> _bits;
};
测试代码如下:
void test_bit_set()
{
bitset<100> bs;
bs.Set(5);
bs.Set(10);
bs.Set(20);
cout << bs.test(5) << endl;
cout << bs.test(10) << endl;
cout << bs.test(20) << endl;
bs.Reset(20);
bs.Reset(10);
bs.Reset(5);
cout << bs.test(5) << endl;
cout << bs.test(10) << endl;
cout << bs.test(20) << endl;
}
运行结果如下:
边栏推荐
猜你喜欢
随机推荐
为什么刀具数据库无法打开?
shader学习笔记(五)
“我“是一名测试/开发程序员,小孙的内心独白......
制定量化交易策略的基本步骤有哪些?
2022/8/9 考试总结
力扣:518. 零钱兑换 II
SRv6性能测量
都在说云原生,那云原生到底是什么?
LiveData : Transformations.map和 Transformations.switchMap用法
2022-08-09 mysql/stonedb-慢SQL-Q16分析
多线程是同时执行多个线程的吗
Forbidden (CSRF token missing or incorrect.): /
linux上使用docker安装redis
VR全景拍摄如何拍摄?如何使用拍摄器材?
集群的基础形式
生成NC文件时,报错“未定义机床”
Sun Zhengyi lost 150 billion: it was expensive at the beginning
直播预告 | ICML 2022 11位一作学者在线分享神经网络,图学习等前沿研究
2020年度SaaS TOP100企业名单
Qt 消息机制和事件