【C++位图】构建灵活的空间效率工具

目录

  • 位图
    • 位图的基本概念
    • 如何用位图表示数据
    • 位图的基本操作
      • set
      • reset
      • test
    • 封装位图的设计
  • 总结

在这里插入图片描述

在计算机科学中,位图(Bitmap)是一种高效的空间管理数据结构,广泛应用于各种场景,如集合操作、图像处理和资源管理。与传统的数据结构相比,位图通过使用二进制位来表示元素的存在与否,从而显著降低存储空间的消耗。然而,尽管位图的原理简单,其实现与操作却可能面临诸多挑战。

在本文中,我们将深入探讨如何在 C++ 中封装位图数据结构,重点介绍其基本操作、性能优化以及实际应用。通过封装,我们不仅可以提高代码的可读性和可维护性,还能为后续的功能扩展打下坚实的基础。让我们一起来揭开位图的神秘面纱,探索其在现代编程中的价值。

位图

位图的基本概念

位图(Bitmap)是一种用于高效表示集合的数据结构,其核心思想是使用二进制位来指示某个元素是否存在。在位图中,每个元素对应一个二进制位,若该元素存在,则对应的位为1;若不存在,则为0。这种表示方式使得位图能够在存储上以极高的空间效率来管理大规模数据。
位图特别适用于需要频繁查询和更新的场景,如数据库索引、图像处理和网络协议等。在这些应用中,位图不仅能节省存储空间,还能提高算法的执行速度。
假如我们有几十亿个数据需要在当中查找某个数,我们需要在当中查看某个数是否存在,很容易想到的方法是先用数组存起来,然后再进行排序,排序之后利用二分进行查找,如果单看时间复杂度其实是不大的,这里的问题其实不在算法上,而是在我们该如何存储着几十亿个数据,假如我们有四十亿个数据如果存储起来也需要16g的内存,消耗是相当大的,所以我们就引入了位图用来处理海量数据,这40亿个数据我们可以用40亿个比特位来表示,比特位只有1和0,1表示存在0表示不存在。40亿个比特位大约500mb,节省了将近33倍的空间,效率是相当大的。

如何用位图表示数据

我们是无法操作比特位的,C++操作内存的最小单位是字节,所以我们只能通过位运算来控制比特位,所以我们用 int类型的vector来控制。
在这里插入图片描述我们通过一个vector控制,每个int位可以控制32个数。

位图的基本操作

位图有三个核心接口:reset,set还有一个test。
reset表示将指定数对应的比特位设置为0。
set表示将指定数对应的比特位设定为1。
test表示检测指定数对应的比特位是0还是1,如果是0返回0,如果是1返回1。

首先对位图我们需要一个:

std::vector<int> _bs;

set

void set(size_t x)
{size_t i = x / 32,j = x % 32;//需要把这个整形的第j位标记为1//bs或等于1左移七位_bs[i] |= (1 << j);
}

先将给定数的位置算出来,i表示在第几个int,j表示在比特位的第多少位。
由于这里我们需要将第j位设置为1,而且不能动其他位,所以可以想到位运算(|),先将1左移j位(左移不是表示向左移动,而是表示低位向高位移动),由于两个数进行按位或运算是如果有1结果就是1,0|1也是1,0|0也是0,所以这里不会改变其他位的数。
在这里插入图片描述

reset

void reset(size_t x)
{size_t i = x / 32, j = x % 32;//标记为0左移j位然后取反,直接与等_bs[i]  &= (~(1 << j));
}

reset和set很相似,set需要将当前位置设置为1,reset是要将指定数对应的比特位设置为0,所以我们会想到位运算&,还是先找到对应的byte位,然后将1移到对应的数的比特位的位置,因为两个数的&运算的特点是只要有0就是0,两个都为1才是1,所以这里只需要将除对应比特位以外的所有位置变为1然后将对应比特位位置变为0即可。
在这里插入图片描述

test

bool test(size_t x)
{size_t i = x / 32, j = x % 32;//取到j位置的值return _bs[i] & (1 << j);
}

test只需要取到对应数的比特位即可。

封装位图的设计

//飞类型模版参数
template<size_t N>
class bit_set
{
public:bit_set(){//一个整数是32个位,所以这里要n个位需要除以32//向上取整(如果开60个位60/32=1,那么久少开了一个位)_bs.resize(N / 32 + 1);}//位图的三个核心接口//x映射的位标记为1void set(size_t x){size_t i = x / 32;size_t j = x % 32;//需要把这个整形的第j位标记为1//bs或等于1左移七位_bs[i] |= (1 << j);}//把之前标记的位标记为0void reset(size_t x){size_t i = x / 32, j = x % 32;//标记为0左移j位然后取反,直接与等_bs[i]  &= (~(1 << j));}//x映射的位置是0返回假,是1返回真bool test(size_t x){size_t i = x / 32, j = x % 32;//取到j位置的值return _bs[i] & (1 << j);}
private://C/C++中定义的最小单位是一个字节//一个int是32个位std::vector<int> _bs;
};

总结

在本文中,我们深入探讨了位图数据结构的基本概念及其在 C++ 中的封装实现。位图通过使用二进制位高效地表示集合,极大地节省了内存空间,并在查询和操作上提供了卓越的性能。通过封装,我们不仅提升了代码的可读性和可维护性,还为后续的扩展奠定了基础。

在实际应用中,位图能够在资源管理、网络协议等多个领域发挥重要作用。随着数据规模的不断增长,掌握位图的使用和优化将对程序员的技能提升至关重要。希望本文能为你在数据结构和算法的学习中提供有价值的参考和启发。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1547207.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

什么是开放式耳机?具有什么特色?非常值得入手的蓝牙耳机推荐

开放式耳机是当下较为热门的一种耳机类型。它具有以下特点&#xff1a; 设计结构&#xff1a; 呈现开放式的构造&#xff0c;不会完全堵住耳道。如此一来&#xff0c;外界声音能够较容易地被使用者听到&#xff0c;在使用耳机时可以保持对周围环境的察觉。比如在户外&#xf…

绿色新纪元:光伏技术飞跃与能源体系重塑

近年来&#xff0c;光伏电池技术取得了突破性进展。新型高效光伏材料如钙钛矿、有机光伏等不断涌现&#xff0c;这些材料在转换效率和稳定性上均表现出色&#xff0c;为光伏产业注入了新的活力。同时&#xff0c;光伏组件的智能化、轻量化设计也日益成为趋势&#xff0c;使得光…

Go基础学习06-Golang标准库container/list(双向链表)深入讲解;延迟初始化技术;Element;List;Ring

基础介绍 单向链表中的每个节点包含数据和指向下一个节点的指针。其特点是每个节点只知道下一个节点的位置&#xff0c;使得数据只能单向遍历。 示意图如下&#xff1a; 双向链表中的每个节点都包含指向前一个节点和后一个节点的指针。这使得在双向链表中可以从前向后或从后…

403高效绕过目录扫描工具

403高效绕过目录扫描工具 简介 在安全测试中&#xff0c;安全测试人员信息收集时可使用此工具来进行目录枚举&#xff0c;目录进行指纹识别&#xff0c;枚举出来的403状态目录可尝试进行绕过&#xff0c;绕过403有可能获取管理员权限&#xff0c;不影响dirsearch原本功能使用。…

提升效率,C4D云渲染教程来了

因为C4D主要搭配的渲染器OCtane和Redshift都是GPU渲染器&#xff0c;阿诺德渲染器也可能直接用GPU渲染&#xff0c;所以大部分C4D渲染农场都支持用RTX2080、3090、4090系列显卡云渲染&#xff0c;云渲染追求速度&#xff0c;分机渲染任务&#xff0c;比如分100台机器渲染一个相…

wireshark1

注意看title&#xff0c;管理员的密码即为答案&#xff0c;那么咱们就直接去过找POST请求的数据包就可以了 找到flag&#xff0c;游戏结束~

TOGAF®架构开发方法:构建数字化转型新时代的正式权威指南

The Open Group与AZone权威出品&#xff0c;值得信赖 《TOGAF架构开发方法》培训课程&#xff08;点击即可学习&#xff09; 全球最具影响力的数字化转型架构出品方The Open Group 专注于企业架构师职业发展的平台AZone联合推出 The Open Group&#xff1a;行业领导者的信赖…

每日OJ题_牛客_NC40链表相加(二)_链表+高精度加法_C++_Java

目录 牛客_NC40链表相加&#xff08;二&#xff09;_链表高精度加法 题目解析 C代码 Java代码 牛客_NC40链表相加&#xff08;二&#xff09;_链表高精度加法 链表相加(二)_牛客题霸_牛客网 题目解析 模拟⾼精度加法的过程&#xff0c;只不过是在链表中模拟。 C代码 /*…

FreeRTOS(四)FreeRTOS列表与列表项

目录 列表 列表项 迷你列表项 列表和列表项的关系 列表相关API函数 列表初始化 列表项初始化 列表项插入 列表项末尾插入 列表项删除 列表遍历 在 FreeRTOS 中&#xff0c;列表&#xff08;List&#xff09;和列表项&#xff08;ListItem&#xff09;是核心数据结构&…

linux内核双向链表使用list klist

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、list和klist是什么&#xff1f;二、代码示例1.list2.klist 总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; linux内核中大量使…

上市一周暴涨20%,美的的出海之路开了个好头

“宁可走错一步&#xff0c;也不能走错半步”&#xff0c;这是美的集团创始人何享健的名言&#xff0c;也代表着美的集团在扩张方面长期以来一贯的风格&#xff1a;稳健。 映射在当下&#xff0c;就是当老对手海尔智家于2020年率先登陆港交所&#xff0c;国际化策略初显成效以…

JavaWeb 13.HTTP协议

和自己的情绪共处&#xff0c;永远保持乐观 —— 24.9.26 一、HTTP简介 HTTP 超文本传输协议 (HTTP-Hyper Text transfer protocol)&#xff0c;是一个属于应用层的面向对象的协议&#xff0c;由于其简捷、快速的方式&#xff0c;适用于分布式超媒体信息系统。它于1990年提出&a…

考研数据结构——C语言实现归并排序

包含头文件&#xff1a;程序首先包含了标准输入输出库stdio.h&#xff0c;以便使用printf等函数进行输入输出操作。 定义数组和数组大小&#xff1a;定义了一个宏N&#xff0c;其值为5&#xff0c;表示数组q的长度。数组q被初始化为{5, 3, 8, 4, 2}&#xff0c;这是我们要排序…

BFS 解决 FloodFill 算法

BFS 解决 FloodFill 算法 题目一&#xff1a; 图像渲染1. 题⽬链接&#xff1a;2. 题⽬描述&#xff1a;3. 算法思路&#xff1a;4.代码 题目二&#xff1a; 岛屿数量1. 题⽬链接&#xff1a;2. 题⽬描述&#xff1a;3. 算法思路&#xff1a;4.代码 题目三&#xff1a;被围绕的…

论文不会写怎么办?推荐这5款AI论文工具帮你一键搞定!

在当今的学术研究和写作领域&#xff0c;AI论文工具已经成为不可或缺的助手。这些工具不仅能够提高写作效率&#xff0c;还能帮助研究者生成高质量的论文。本文将推荐五款优秀的AI论文工具&#xff0c;并特别推荐千笔-AIPassPaper&#xff0c;以帮助读者更好地完成学术写作任务…

OJ在线评测系统 后端 判题机模块预开发 架构分析 使用工厂模式搭建

判题机模块预开发(架构师)(工厂模式) 判题机模块 是为了把代码交个代码沙箱去处理 得到结果返回 代码沙箱 梳理判题模块和代码沙箱的关系 判题模块&#xff1a;调用代码沙箱 把代码和输入交给代码沙箱去执行 代码沙箱&#xff1a;只负责接受代码和输入 返回编译的结果 不负…

初始化的代码块和@PostConstruct有什么区别

背景 在实际开发中&#xff0c;我们经常会需要进行一些初始化操作&#xff0c;比如进行一些预加载和赋值之类的。在代码中&#xff0c;常见的有通过静态代码块、非静态代码块&#xff0c;PostConstruct来实现初始化。那么既然他们都可以实现初始化操作&#xff0c;那么他们有什…

Ubuntu 开机自启动 .py / .sh 脚本,可通过脚本启动 roslaunch/roscore等

前言 项目中要求上电自启动定位程序&#xff0c;所以摸索了一种 Ubuntu 系统下开机自启动的方法&#xff0c;开机自启动 .sh 脚本&#xff0c;加载 ROS 环境的同时启动 .py 脚本。在 . py 脚本中启动一系列 ROS 节点。 一、 .sh 脚本的编写 #!/bin/bash # gnome-terminal -- …

JetPack03-ViewModel 保证界面数据稳定性

前提 Activity横竖屏切换后&#xff0c;Activity中的数据会丢失。 因为横竖屏切换后&#xff0c;Activity会销毁重建&#xff0c;生命周期会执行onPause->onStop->onDestroy->onCreate->onStart->onReusme。 简介 ViewModel能保证Activity中数据的稳定性&…

【C++】map和set的介绍和使用

1.序列式容器与关联式容器 序列式容器&#xff1a; 底层为线性序列的数据结构&#xff0c; 里面存储的是元素本身 。如vector/list/string/deque/forward_list。 关联式容器&#xff1a; 也是用来存储数据的&#xff0c;于序列式容器不同的是&#xff0c; 里面存储的是<key&…