前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >C++语法中bitset位图介绍及模拟实现

C++语法中bitset位图介绍及模拟实现

作者头像
芯动大师
发布于 2023-10-14 00:44:02
发布于 2023-10-14 00:44:02
27600
代码可运行
举报
文章被收录于专栏:防止网络攻击防止网络攻击
运行总次数:0
代码可运行
一、位图的引入

先来看下边一道面试题:

给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。

经过我们之前的学习,我们可能会有以下的思路:

  • 对这些数进行排序,再通过二分算法,查找这个数是否存在
  • 插入到unordered_set中,使用find函数查找是否存在

上述方法看起来还不错,二分查找算法时间复杂度为logN,而插入到unordered_set中时间复杂度为O(N),而查找时时间复杂度为O(1),但是都有一个问题就是要将空间不足,40亿个无符号整形,需要160亿字节的空间,大概就是16GB的空间,一般计算机的内促都是4G或者8G,所以空间不足,此时就有了位图的方法来解决:

数据是否在给定的整形数据中,结果是在或者不在,刚好是两种状态,那么可以使用一个二进制比特位来代表数据是否存在的信息,如果二进制比特位为1,代表存在,为0代表不存在。比如:

对于上图来说,有一个整形数组,我们可以使用直接定址法对数组的数据进行映射,但是与之前不同的是,此时只是使用一个比特位来代表一个整形数据,当这个数存在时,比特位置1,不存在时,比特位置0,此时就可以大大节省空间资源,无符号整数只有2的32次方个,所以最多开2的32次方个空间,一个空间为一个比特,所以最终只需要512MB的空间。但是我们不能按照位来空间,最少必须一个字节,所以我们就每次开一个字节的空间,也就是8个比特位,将8位当做一个整体来处理,对要保存的数据除8就是第几个字节,对保存的数据模8就是在这个字节中的第几个位置。

二、位图的概念

所谓位图,就是用每一位来存放某种状态,适用于海量数据,数据无重复的场景。通常是用来判断某个数据存不存在的。

那么位图还有哪些应用呢?

  • 快速查找某个数据是否在一个集合中
  • 排序 + 去重
  • 求两个集合的交集、并集等
  • 操作系统中磁盘块标记

位图模拟实现

一、构造函数

由于不能按位开空间,所以我们选择每次开一个字节的空间,由于有范围最大为N,一位关联一个数据,所以需要开N/8个字节的空间,但是有时可能不能整除,所以要开N/8+1个字节的空间。所以

直接在构造函数中开好空间:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
bitset()
		{
			_bits.resize(N / 8 + 1,0);
		}
二、set,reset,test函数

set函数的作用是对位图中的某一位进行填充

i就表示是第几个字节,而j表示该位在该字节中的第几位,所以对1进行左移j位后与该字节按位或,按位或的作用时不论该位为0还是为1,都将该位变为1。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void set(size_t x)
		{
			int i = x / 8;
			int j = x % 8;
			_bits[i] |= (1 << j);
		}

reset的作用是将某一位清空

同样的将要清空的那一位置为0,进行按位与,不论原本该位是0还是1,都将该位置0

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void reset(size_t x)
		{
			int i = x / 8;
			int j = x % 8;
			_bits[i] &= ~(1 << j);
		}

test的作用是检测位图中某一位是否存在

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
bool test(size_t x)
		{
			int i = x / 8;
			int j = x % 8;
			return _bits[i] & (1 << j);
		}
三、代码测试
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void test_bit_set1()
	{
		bitset<100> bs1;
		bs1.set(8);
		bs1.set(9);
		bs1.set(20);
		cout << bs1.test(8) << endl;
		cout << bs1.test(9) << endl;
		cout << bs1.test(20) << endl;
		bs1.reset(8);
		bs1.reset(9);
		bs1.reset(20);
		cout << bs1.test(8) << endl;
		cout << bs1.test(9) << endl;
		cout << bs1.test(20) << endl;
	}
四、完整代码
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
namespace tmt
{
	template<size_t N>
	class bitset
	{
	public:
		bitset()
		{
			_bits.resize(N / 8 + 1,0);
		}
		void set(size_t x)
		{
			int i = x / 8;
			int j = x % 8;
			_bits[i] |= (1 << j);
		}
		void reset(size_t x)
		{
			int i = x / 8;
			int j = x % 8;
			_bits[i] &= ~(1 << j);
		}
		bool test(size_t x)
		{
			int i = x / 8;
			int j = x % 8;
			return _bits[i] & (1 << j);
		}
	private:
		vector<char> _bits;
	};
	void test_bit_set1()
	{
		bitset<100> bs1;
		bs1.set(8);
		bs1.set(9);
		bs1.set(20);
		cout << bs1.test(8) << endl;
		cout << bs1.test(9) << endl;
		cout << bs1.test(20) << endl;
		bs1.reset(8);
		bs1.reset(9);
		bs1.reset(20);
		cout << bs1.test(8) << endl;
		cout << bs1.test(9) << endl;
		cout << bs1.test(20) << endl;
	}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-10-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——14.哈希(3)(布隆过滤器和位图)
bitset 是 C++ 标准库中的一个类模板,主要用于管理固定大小的位集合。它能够在一个单一的对象中存储多个二进制位,非常适合用于需要高效存储和快速访问位信息的场景。
hope kc
2024/10/24
1440
移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——14.哈希(3)(布隆过滤器和位图)
【C++】位图应用 | 布隆过滤器
给40亿个不重复的无符号整数,没排过序,给一个无符号整数,如何快速判断一个数是否在这40亿个数中
lovevivi
2023/10/17
2050
【C++】位图应用 | 布隆过滤器
【C++高阶】哈希—— 位图 | 布隆过滤器 | 哈希切分
之前我们已经在这篇文章中 【C++高阶】哈希函数底层原理全面探索和深度解析-CSDN博客
IsLand1314
2024/10/15
1670
【C++高阶】哈希—— 位图 | 布隆过滤器 | 哈希切分
C++ 哈希的应用【位图】
位图(bitset)是一种特殊的数据结构,仅仅依靠 0、1 表示当前位置是否有数据存在,常用于对查找速度和存储空间有着高要求的场景中,除此之外,位图还可以配合宏定义,实现同时传递多个参数,比如系统调用 open,其中的参数2(打开方式)就是一个简单的位图结构
北 海
2023/07/28
3280
C++ 哈希的应用【位图】
【C++】哈希应用:位图 哈希切分 布隆过滤器
1. 大厂经典的面试题,给你40亿个不重复的无符号整数,让你快速判断一个数是否在这40亿个数中,最直接的思路就是遍历这40亿个整数,逐一进行比对,当然这种方式可以倒是可以,但是效率未免太低了。 另一种方式就是排序+二分的查找,因为二分查找的效率还是比较高的,logN的时间复杂度,但是磁盘上面无法进行排序,排序要支持下标的随机访问,这40亿个整数又无法加载到内存里面,你怎么进行排序呢?所以这样的方式也是不可行的。 那能不能用红黑树或者哈希表呢?红黑树查找的效率是logN,哈希表可以直接映射,查找的效率接近常数次,虽然他们查找的效率确实很快,但是40亿个整数,那就是160亿字节,10亿字节是1GB,16GB字节红黑树和哈希表怎么能存的下呢?这还没有算红黑树的三叉链结构,每个结点有三个指针,而且哈希表每个结点会有一个next指针,算上这些的话需要的内存会更大,所以用红黑树或哈希表也是无法解决问题的。
举杯邀明月
2023/04/12
6320
【C++】哈希应用:位图 哈希切分 布隆过滤器
【C++修炼之路】24.哈希应用--位图
数据是否在给定的整形数据中,结果是在或者不在,刚好是两种状态,那么可以使用一个二进制比特位来代表数据是否存在的信息,如果二进制比特位为1,代表存在,为0代表不存在。
每天都要进步呀
2023/03/28
2710
【C++修炼之路】24.哈希应用--位图
哈希应用
所谓位图,就是用每一个比特位来存放某种状态,适用于海量数据,数据无重复的场景。通常是用来判断某个数据存不存在的
芝士就是菜
2023/04/20
4370
哈希应用
【C++从小白到大牛】位图讲解
给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。【腾讯】
用户11316056
2024/10/16
1070
【C++从小白到大牛】位图讲解
极致高效的数据处理:位图、布隆过滤器与哈希切分的奇妙之旅
本文将带领你深入探索哈希的三大高效应用——位图、布隆过滤器和哈希切分。它们如同精巧的齿轮,共同驱动着现代计算系统的高效运作。从减少存储空间到加速查找效率,从数据去重到流式处理,这些技术在幕后悄然发挥着巨大的力量。让我们一起揭开哈希算法的神秘面纱,领略数据处理的艺术之美。
suye
2024/11/19
1950
极致高效的数据处理:位图、布隆过滤器与哈希切分的奇妙之旅
【C++进阶】位图/布隆过滤器与海量数据处理
我们知道数据的最小存储位是比特(bite),每个比特位只能是0或1,我们用1和0来表示在或不在,或是其它类型的状态信息,这种结构称作位图。
aosei
2024/01/23
1620
【C++进阶】位图/布隆过滤器与海量数据处理
【数据结构】哈希经典应用:位图——[深度解析](8)
YY的秘密代码小屋
2024/01/23
3160
【数据结构】哈希经典应用:位图——[深度解析](8)
C++:哈希拓展-位图
第二种方法就是先排序+二分查找:肯呢个有些人会觉得,排序的代价太大了;其实不然,我们只需要排序一次那么接下来的查找就好办了; 对于二分查找,效率是O(logn),根据2^10=1024,那2^30的数量级就是10^9,就已经上升到亿了,2^32大约就是40亿;所以我们使用二分在40亿个数中查找一个数最多只需要查找32次就可以了,效率是相当客观的;
啊QQQQQ
2024/11/19
580
C++:哈希拓展-位图
C++哈希应用-位图/布隆过滤器/海量数据处理
C++位图/布隆过滤器/海量数据处理 零、前言 一、位图 1、位图概念 2、位图接口的介绍以及实现 3、位图的应用 二、布隆过滤器 1、布隆过滤器概念和介绍 2、布隆过滤器的操作及实现 3、布隆过滤器的分析 三、海量数据处理 零、前言 本章主要讲解C++中对哈希的应用有关方面的内容,位图,布隆,海量数据处理 一、位图 1、位图概念 位图概念: 位图其实就是哈希的变形,同样通过映射来处理数据,只不过位图本身并不存储数据,而是存储标记 通过一个比特位来标记这个数据是否存在,1代表存在,0代表不
用户9645905
2022/11/30
5430
C++哈希应用-位图/布隆过滤器/海量数据处理
位图/布隆过滤器/海量数据处理方式
所谓位图,就是用每一位来存放某种状态,适用于海量数据,数据无重复的场景。通常是用来判断某个数据存不存在的。
二肥是只大懒蓝猫
2023/03/30
3960
位图/布隆过滤器/海量数据处理方式
哈希的应用——位图
所以上面这些思路都不太合适,而且我们这里只是要判断在不在,其实没必要把它们全部存起来。
YIN_尹
2024/01/23
1990
哈希的应用——位图
位图与布隆过滤器
此篇文章针对大量数据进行筛选或者判断重复,存在等一系列侧重于在特定空间,时间等允许范围内进行选择的问题提出解决方案。
羑悻的小杀马特.
2025/01/23
1000
位图与布隆过滤器
【C++航海王:追寻罗杰的编程之路】哈希的应用——位图 | 布隆过滤器
位图的概念:所谓位图,就是用每一位来存放某种状态,适用于海量数据,数据无重复的场景。通常是用来判断某个数据是否存在的。
枫叶丹
2024/07/15
1280
【C++航海王:追寻罗杰的编程之路】哈希的应用——位图 | 布隆过滤器
C++位图
其次是set和哈希表。set自动可以排序且在红黑树中查找速度也很快。但要把40亿个整数加上红黑树的节点(三叉链外加颜色)放进内存里,内存明显不够,不可取;哈希表同样是把40亿个整数外加节点放进内存里,内存明显不够,也不可取。
梨_萍
2023/04/24
4860
C++位图
【C++高阶】哈希之美:探索位图与布隆过滤器的应用之旅
前言:在数据科学的浩瀚星空中,哈希函数犹如一颗璀璨的星辰,以其独特的光芒照亮了数据处理的每一个角落。哈希,这一简单而强大的技术,通过将任意长度的输入(如字符串、数字等)映射到固定长度的输出(即哈希值),实现了数据的快速定位与索引。然而,哈希的魅力远不止于此,当它与位图和布隆过滤器相结合时,更是催生出了一系列高效且实用的数据处理方案
Eternity._
2024/08/05
1110
【C++高阶】哈希之美:探索位图与布隆过滤器的应用之旅
C++:位图和布隆过滤器
问题:给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在 这40亿个数中。【腾讯】
小陈在拼命
2024/05/10
1260
C++:位图和布隆过滤器
相关推荐
移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——14.哈希(3)(布隆过滤器和位图)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验