【C++】位图

article/2025/7/27 1:44:42

        位图(Bitmap)是一种用于高效表示集合的数据结构,其核心思想是使用二进制位来指示某个元素是否存在。在位图中,每个元素对应一个二进制位,若该元素存在,则对应的位为1;若不存在,则为0。

        背景:假设有这样一个需求:在20亿个随机整数中找出某个数m是否存在其中,并假设32位操作系统,4G内存。

        C++中int占4个字节一个字节8个比特位。

如果每个数字用int存储,那就是20亿个int,因而占用的空间约为  (2000000000*4/1024/1024/1024)≈7.45G

如果按位存储就不一样了,20亿个数就是20亿位,占用空间约为  (2000000000/8/1024/1024/1024)≈0.233G

        问题:如何表示这一个数存不存在?

        每一位表示一个元素,标识为1表示存在,标识为0表示不存在。

        假如,我们存了10,20,30,40,48,那我们在位图中如何表示?

下面我就用从左到右依次增高的地址来表示:

既然是在位图中,我们使用常规的遍历肯定是不行的。

那该如何查找存不存在????这里我们要先 

Element / 32  -->除32(int占32位)

Element%32  -->取模

这样我们就知道他位于哪个字节中的哪个位置了。因此可以判断是否存在。

既然了解了上面的知识,我们模拟一下C++中STL容器中的bitset吧。

	template<size_t N>class bit_set{public:bit_set(){_bs.resize(N / 32 + 1);}// x映射的位标记成1void set(size_t x){size_t i = x / 32;size_t j = x % 32;_bs[i] |= (1 << j);}// x映射的位标记成0void reset(size_t x){size_t i = x / 32;size_t j = x % 32;_bs[i] &= (~(1 << j));}// x映射的位是1返回真// x映射的位是0返回假bool test(size_t x){size_t i = x / 32;size_t j = x % 32;return _bs[i] & (1 << j);}private:std::vector<size_t> _bs;};

当我们设置一个数字进入位图里面,也就是我们要把相应的位图设置为1,同时又不能改变其他的位置标识。如何操作呢?这里我使用的是|。举个例子吧,下面这两个是位,我们进行按位或操作

0100 0 0000

0000 1 0000

结果就是

0100 1 0000

当我们要取消一个数字进入位图里面,也就是我们要把相应的位图设置为0,同时又不能改变其他的位置标识。如何操作呢?这里我使用的是&。举个例子

0100 1 1010

1111 0 1111

结果

0100 0 1010

优点:

位图(Bitmap)在单个元素的查找、插入、删除操作上的时间复杂度可以达到 O(1)。

快速排序:

假设我们要对0-7内的5个元素(4,7,2,5,3)排序(这里假设这些元素没有重复),我们就可以采用Bit-map的方法来达到排序的目的。

要表示8个数,我们就只需要8个Bit(1字节),首先我们开辟1字节的空间,将这些空间的所有Bit位都置为0,然后将对应位置为1。

最后,遍历一遍Bit区域,将该位是一的位的编号输出(2,3,4,5,7),这样就达到了排序的目的,时间复杂度O(n)

缺点:

只能用于整形。


        题目:1.给定100亿个数字,设计算法找到只出现一次的整数?

                    2.一个文件有100亿个整数,1G内存,设计算法找到出现次数不超过2的所有整数  

这里我们可以实现两个位图来实现一下。如果第一个位图为0第二个位图为1,说明出现了1一次,

如果第一个位图为1第二个位图为0,说明出现了2次,如果第一个位图为1第二个位图为1,说明出现了2次及以上。

	template<size_t N>class two_bit_set{public:void set(size_t x){bool bit1 = _bs1.test(x);bool bit2 = _bs2.test(x);if (!bit1 && !bit2) // 00 -> 01{_bs2.set(x);}else if (!bit1 && bit2) // 01->10{_bs1.set(x);_bs2.reset(x);}else if (bit1 && !bit2) // 10 -> 11{_bs1.set(x);_bs2.set(x);}}private:bit_set<N> _bs1;bit_set<N> _bs2;};

 


http://www.hkcw.cn/article/OisEuaopty.shtml

相关文章

初学c语言21(文件操作)

一.为什么使用文件 之前我们写的程序的数据都是存储到内存里面的&#xff0c;当程序结束时&#xff0c;内存回收&#xff0c;数据丢失&#xff0c; 再次运行程序时&#xff0c;就看不到上次程序的数据&#xff0c;如果要程序的数据一直保存得使用文件 二.文件 文件一般可以…

回车键为什么叫做“回车键”?

Enter键&#xff0c;也就是 “回车键”&#xff0c; 大家应该都不陌生。 可你知道它为什么叫“回车键”&#xff0c; 而不叫“输入键”、“登记键”嘛&#xff1f; 这要从机械英文打字机说起 因为电脑的普及&#xff0c;打字机几乎消失匿迹。 有的小伙伴们也许在小时候用过…

以太联Intellinet 分享:PoE 技术在医疗保健行业的创新应用

在当今科技飞速发展的时代&#xff0c;物联网(IoT)在医疗领域的应用正呈现出蓬勃兴起的态势。全球各地的医院以及老年生活中心纷纷引入物联网智能医疗解决方案&#xff0c;以实现设施运营的高效化与智能化。而在这背后&#xff0c;以太网供电(PoE)技术发挥着关键作用&#xff0…

大语言模型的技术原理与应用前景:从Transformer到ChatGPT

目录 摘要 1. 引言 2. Transformer架构核心原理 2.1 自注意力机制 2.2 位置编码 2.3 前馈神经网络 3. 从GPT到ChatGPT的演进 3.1 GPT系列模型架构 3.2 训练流程优化 4. 应用场景与案例分析 4.1 代码生成 4.2 文本摘要 4.3 问答系统 5. 挑战与未来方向 5.1 当前技…

CSS Day06

1.定位-相对和绝对和固定 (1)相对定位 position: relative; top: 100px; left: 200px; &#xff08;2&#xff09;绝对定位 就是子选择则器要用绝对定位&#xff0c;父选择器要用相对定位。 如果没有遵守此规则&#xff0c;那么小标签会跑到浏览器最角落&#xff1a; &#…

2025年5月24号高项综合知识真题以及答案解析(第1批次)

2025年5月24号高项综合知识真题以及答案解析

PowerDesigner通过SQL反向生成类图

PowerDesigner通过SQL反向生成类图 背景操作步骤步骤1: 选择这个步骤2: 目前我是选择的这个步骤3: 选择这个 其他 背景 工作学习 操作步骤 步骤1: 选择这个 步骤2: 目前我是选择的这个 步骤3: 选择这个 其他 其他同事告诉我的, 我还没有亲自尝试, 应该问题不大. 尝试后再反…

驱动灯珠芯片LT3743手册理解

1.引脚功能 1.EN/UVLO EN/UVLO引脚用作启用引脚&#xff0c;可在1.55V时开启内部电流偏置核心和子稳压器。该引脚没有上拉或下拉功能&#xff0c;因此正常工作需要电压偏置。当电压降至约0.5V时&#xff0c;系统将完全关闭。即EN/UVLO引脚的输入电压在1.55V至6V之间即可。 2.…

在 Mac 下 VSCode 中的终端使用 option + b 或 f 的快捷键变成输入特殊字符的解决方案

前言 在终端里&#xff0c;我们可以使用 option b 和 option f 来在我们输入的命令中进行快速的前后调整光标&#xff0c;但是&#xff0c;在未设置的情况下&#xff0c;在 MacOS 中&#xff0c;会变成输入特殊字符。 普通键盘上是 alt b 和 alt f &#xff0c;只是叫法不…

晨控CK-FR08与西门子PLC配置Profinet通讯连接操作手册

晨控CK-FR08与西门子PLC配置Profinet通讯连接操作手册 晨控CK-FR08系列作为晨控智能工业级别RFID读写器,支持大部分工业协议如RS232、RS485、以太网。支持工业协议Modbus RTU、Modbus TCP、Profinet、EtherNet/lP、EtherCat以及自由协议TCP/IP等。 本期主题&#xff1a;围绕CK…

【高能计算机】海思主板的特点和应用

在科技飞速发展的今天&#xff0c;主板作为电子设备的核心组件&#xff0c;其性能和功能直接影响着整个系统的运行效率和稳定性。继飞腾主板和龙芯主板的出现之后&#xff0c;高能计算机作为中国工控主板的研发生产商&#xff0c;紧跟时代发展的步伐&#xff0c;又推出一款海思…

从认识AI开始-----解密LSTM:RNN的进化之路

前言 我在上一篇文章中介绍了 RNN&#xff0c;它是一个隐变量模型&#xff0c;主要通过隐藏状态连接时间序列&#xff0c;实现了序列信息的记忆与建模。然而&#xff0c;RNN在实践中面临严重的“梯度消失”与“长期依赖建模困难”问题&#xff1a; 难以捕捉相隔很远的时间步之…

基于javaweb的JSP+Servlet家政服务系统设计与实现(源码+文档+部署讲解)

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…

银行数字化应用解决方案

行业背景 银行业数字化转型已成为大势所趋&#xff0c;新技术浪潮为银行带来巨大的创新机遇&#xff0c;移动互联催生全新的用户体验需求&#xff0c;大数据应用带来深刻的客户洞察。但错综复杂的业务场景、严格的监管和合规要求、复合型人才的匮乏等问题&#xff0c;严重制约…

视频加密技术和防翻录技术有哪些?

更新&#xff1a;问答播放器的截图效果。 摘要&#xff1a;视频加密技术通过分布式编码、切片加密、动态水印等手段保护内容安全&#xff0c;防止盗录和二次分发。主流方案包括&#xff1a;1&#xff09;VRM12采用混合算法加密与密码本混淆&#xff1b;2&#xff09;H5优化HLS机…

嵌入式开发学习日志(linux系统编程--进程(4)——线程锁)Day30

扩&#xff1a;typedef三种用法&#xff08;简化代码编写&#xff09; 一、线程的控制——互斥和同步 &#xff08;一&#xff09;实例引入 1、示例&#xff1a; 运行结果&#xff1a; 两个线程都在运行&#xff0c;出现问题原因&#xff1a;资源竞争&#xff08;对全局变量都…

从图像处理到深度学习:直播美颜SDK的人脸美型算法详解

在直播的镜头前&#xff0c;每一位主播都希望自己“光彩照人”。但在高清摄像头无死角的审视下&#xff0c;哪怕是天生丽质&#xff0c;也难免需要一点技术加持。于是&#xff0c;美颜SDK应运而生&#xff0c;成为直播平台提升用户粘性和视觉体验的重要工具。 尤其是在“人脸美…

编译rustdesk,使用flutter、hwcodec硬件编解码

目录 安装相应的环境安装visual studio安装vpkg安装rust开发环境安装llvm和clang编译源码下载源码使用Sciter作为UI的(已弃用)使用flutter作为UI的(主流)下载flutter sdk桥接静默安装最近某desk免费的限制越来越多,实在没办法,平时远程控制用的比较多,只能用rustdesk了,…

Dynamics 365 Business Central EC Sales List 欧洲共同体 (EC) 销售列表

什么是EC Sales List? 是在欧盟境内 开立的具有增值税主体公司的一项报告义务&#xff0c;提供欧盟国家/地区企业之间的跨境交易记录。ESL 的目的是确保这些交易中的所有相关方都支付和申报了适当金额的增值税。 随着出海企业越来越多的在欧州开展业务&#xff0c;此项报告需…

将图片存为二进制流到数据库并展示到前端的实现

使用图片直接存储到数据库中可能会出现以下问题&#xff1a; 1.图片的存储太多了占用数据库的存储空间 2.图片占用内存较大在传输和渲染的情况下会影响应用性能 3.一般情况下是将图片上传云服务器然后数据库存地址&#xff0c;这里讲解的情况只适合图片较少的情景 这里使用…