当前位置:网站首页>位图的详细介绍及模拟实现
位图的详细介绍及模拟实现
2022-06-29 17:38:00 【月半木斤】
目录
位图其实也是应用哈希思想的一种对数据进行快速查找的方法。位图将每个比特位的两种状态来表示数据的存在与否,0表示数据不存在1表示数据存在。实际应用中一般用来在特别大的数据量中查找元素是否存在。
1.位图的简单应用
我们先来看位图映射少量的元素:可以看到在一个数组中有1到22中个别元素如果如果我们每次查找数组中1~22中一个元素是否存在我们每次都需要遍历一遍数组那么是十分慢的,所以我们可以用位图的方式也就是用22个比特位来代表这22个数字的存在状态。那么我们每次判断一个数据是否存在于数组中就可以到位图中去查找。

2.位图海量数据查找
在实际的生活中我们要处理的数据是往往是十分巨大的,例如我们要处理40亿的数据。要求查找40亿的数据中某个元素是否存在那么我们就可以用位图的方式来表示。
首先我们来计算一下不用位图的方式来查询四十亿数据。那么我们首先大概计算一下40亿数据大概是占用多少内存。

我们可以看到40亿数据有大约16个G我们采用内部排序(这里查找的本质就是排序,就是在查找的过程中对每个元素进行排序对比)是很难进行的因为要一次性将16G的数据全部都加载到内存中才可以一一进行查找比对。但是实际中我们的内存可能只有8G或者16G要是将这16G的数据全部都加载到内存中肯定是不合理的。那么就需要外部排序,但是外部排序也需要对文件进行合并排序,排序复杂而且耗费时间。那么我们就可以用位图的方式来轻松解决。

我们可以看到用位图的方式我们只需要申请512M数据就可以实现40亿的数据的查找。
3.STL中位图的介绍和使用
3.1位图的介绍:
可以看到STL中的位图是一个特化的模板直接给出一个无符号的N来表示位图的比特个数。

3.2位图的使用:
- 位图中常见的用法:


- 可以看到这里最低位的位图中的元素在转化为字符串的时候被当作最低位的字符串

4. 位图的应用
4.1. 快速查找某个数据是否在一个集合中
- 我们上面查找数据就是应用位图来实现数的查找
4.2. 排序
- 在上面对于数据查找的过程中因为位图是按照顺序来进行标记数据的,那么在标记的过程中我们其实也就完成了对数据的排序过程。只要在位图中依次将置为1的位读出,那么就是集合中数据的次序。
4.3. 求两个集合的交集、并集等
- 交集:至于交集就更加容易实现了,我们只要将两个位图的每一位进行按位与操作那么得到的新的位图中标记的数据就是原本两个集合的交集。
- 并集:对两个位图进行按位或操作得到的新的位图就是原本两个集合的并集。
4.4. 操作系统中磁盘块标记
(1条消息) Linux下文件系统_月半木斤的博客-CSDN博客
https://blog.csdn.net/weixin_45897952/article/details/123262685?spm=1001.2014.3001.5501

5.位图的模拟实现
#pragma once
#include<iostream>
#include<vector>
#include<assert.h>
using namespace std;
namespace wbx
{
template<size_t N>
class bitset
{
public:
bitset()
:_con(N/8+1),_count(0)
{}
bitset& set(size_t pos, bool val = true)
{
if (pos >= N)
{
assert(true);
}
if (val)
{
_con[pos / 8] |= (1 << (pos % 8));
_count++;
}
else
{
reset(pos);
}
return *this;
}
bitset& reset(size_t pos)
{
_con[pos / 8] &= (~(1 << (pos % 8)));//将其置0
_count--;
return *this;
}
size_t count()
{
//这里也可以用我们实现给好的每个数字对应的位图中数字的个数来计算count的值
//int bitCnttable[256] = {
// 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2,
// 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3,
// 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3,
// 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4,
// 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5,
// 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4,
// 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5,
// 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5,
// 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3,
// 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6,
// 6, 7, 6, 7, 7, 8 };
//_count = 0;
//for (int i = 0; i <_con.size(); i++)
//{
// _count += bitCnttable[_con[i]];
//}
return _count;
}
size_t size()
{
return N;
}
bool test(size_t pos)
{
int temp = _con[pos / 8] & (1 << (pos % 8));
return bool(temp > 0 ? true : false);
}
//?????????????没写出来
unsigned char& operator[](size_t pos)
{//不知道怎样返回一个位置的引用
return _con[pos / 8];
}
string to_string()const
{
string ret;
bool flag = false;
for (int i = 0; i < _con.size(); i++)
{
if (i == _con.size())
{
flag = true;
}
ret += char_tostring(_con[i], flag);
}
return ret;
}
unsigned long to_ulong()const
{
unsigned long ret=0;
string temp = to_string();
int base = 0;
for (int i = temp.size() - 1; i >= 0; i--)
{
ret += (temp[i] - '0')*Nsquare(base);
base++;
}
return ret;
}
private:
long Nsquare(int N)const
{
long ret = 1;
for (int i = 0; i < N; i++)
{
ret *= 2;
}
return ret;
}
string char_tostring(unsigned char num,bool flag)const
//flag用于表示当前是否是最后一位
{
string rets;
while (num)
{
unsigned long temp = num % 2;
num /= 2;
rets.push_back((char)(temp + '0'));
}
if (!flag)
{
while (rets.size() < 8)
{
rets.push_back('0');
}
}
reverse(rets.begin(), rets.end());
return rets;
}
vector<unsigned char> _con;
size_t _count;
};
}
int main()
{
wbx::bitset<23> b;//这里我们因为要表示0-22之间的元素存在情况所以我们要构造23个空间因为还包括0
int array[] = { 1, 3, 7, 4, 16, 12, 13, 19, 22, 18 };
for (int e : array)
{
b.set(e);//将数组中每一个数据都在位图中置为1
}
if (b.test(1))
{
cout << "1 is in bitset" << endl;
}
else
{
cout << "1 is not in bitset" << endl;
}
b.reset(1);//将1位置置为0
if (b.test(1))
{
cout << "1 is in bitset" << endl;
}
else
{
cout << "1 is not in bitset" << endl;
}
cout << b.size() << endl;//位图的个数
cout << b.count() << endl;//位图中被置为1的个数
if (b.test(4))
{
cout << "4 位置在位图中被置为1" << endl;
}
else
{
cout << "4 位置在位图中没有被置为1" << endl;
}
if (b.test(10))
{
cout << "10 位置在位图中被置为1" << endl;
}
else
{
cout << "10 位置在位图中没有被置为1" << endl;
}
cout << b.to_string() << endl;//将位图中每位的设置情况转化为字符串
cout << b.to_ulong() << endl;//将位图中每位的设置情况转化为无符号long型
return 0;
}测试结果:

看到这里如果觉得有用不如点个赞再走吧!!!

边栏推荐
- mysql查询视图命令是哪个
- Inherit Chinese virtues, pay attention to the health of the middle-aged and the elderly, and Yurun milk powder has strong respect for the elderly
- Understanding adapter mode from home office | community essay solicitation
- R language uses user-defined functions to write deep learning leaky relu activation functions and visualize leaky relu activation functions
- R语言将距离矩阵输入给hclust函数进行层次聚类分析,method参数指定两个组合数据点间的距离计算方式、plot函数可视化层次聚类的树状图(dendrogram)
- 浏览器大尺寸截屏
- Browser large screen capture
- Cross border independent station language Unicode to Hebrew
- 剑指 Offer 13. 机器人的运动范围 (BFS)
- Go语言多方式并发实现龟兔赛跑
猜你喜欢
随机推荐
与爱同行,育润走进贫困家庭,助推公益事业
How to create and delete MySQL triggers
C语言练习----指针字符串、链表
How to establish and use KUKA subroutines / functions
Development of freedom free agreement pledge mining system
Freedom自由协议质押挖矿系统开发
KUKA机器人外部轴配置你一定要知道的那些知识
Graduation season | Huawei experts teach interview tips: how to get a high salary offer from a large factory?
R language uses user-defined functions to write deep learning linear activation functions and visualize linear activation functions
R语言将距离矩阵输入给hclust函数进行层次聚类分析,method参数指定两个组合数据点间的距离计算方式、plot函数可视化层次聚类的树状图(dendrogram)
Automatic vending machine
Maidong Internet won the bid of Dajia Insurance Group
Multi mode concurrent implementation of tortoise and rabbit race in go language
首批!腾讯云通过中国信通院政务协同平台解决方案能力评估
Pancakeswap Technology: development principle of gripper robot system
在供应链场景应用中,供应链管理系统扮演什么角色?
正则表达式
Opencv+YOLO-V3实现目标跟踪
Industry application of smart city based on GIS 3D visualization
How to solve MySQL 1045 error in Linux











