C++_位图

       

目录

1、位图的使用

2、位图实现

3、位图与哈希表的区别

4、位图的应用

结语


前言:

        位图采用的是哈希表的思想,哈希表的映射层面是在字节上,而位图的映射层面就是在bit位上。由于bit位所能展现的信息无非只有‘1’和‘0’,所以位图相比于哈希表,前者的功能比较单调,只能判断数据存在与否,若数据存在则bit位置为‘1’,不存在则为‘0’,因此位图使用的场景也不允许有重复数据的出现。

1、位图的使用

         举例,现有数组{1,4,5,9,6};则该数组在哈希表和位图下的映射关系如下图所示:

        如上图所示,若想在位图中找到对应的映射位置,只需要对该数据进行‘/’‘%’的操作即可,比如:要计算数据9在第几个bit位上,则先9/8=1,表示在下标为1的元素上,再用9%8=1,表示在该元素的下标位1的bit位上(也就是9号bit位)。

2、位图实现

        那么如何将位图中的bit位置为‘0’或‘1’呢,可以用一个数字1作为被操作对象,1的二进制序列的最低位是1,其余是0。比如上述的数据9的映射位置是在第二个元素的下标为1的bit位(也就是第二个bit),那么只需要把1左移一个bit位,则移动后1的二进制序列为000..00010(ps:当然此时二进制序列表示的不是1了),然后用该二进制序列直接与第二个元素相或(‘|’),这样就可以把该映射位置的bit位从‘0’变为‘1’了。

        具体操作如下:


        若要把位图中的bit置为0,可以对表达式“1<<j”进行取反操作,然后再与‘&’上映射位置即可。

        位图代码实现如下:

#define _CRT_SECURE_NO_WARNINGS 1#include <vector>
#include <iostream>
using namespace std;template<size_t N>
class bitset
{
public:bitset(){_bits.resize(N / 8 + 1, 0);//位图的大小和初始化}void set(size_t x){size_t i = x / 8;size_t j = x % 8;_bits[i] |= (1 << j);//或-只要有一个为1结果就为1}void reset(size_t x){size_t i = x / 8;size_t j = x % 8;_bits[i] &= ~(1 << j);//或-只要有一个为0结果就为0}bool find(size_t x){size_t i = x / 8;size_t j = x % 8;return _bits[i] & (1 << j);//_bits[i]为1说明该数据存在}private:vector<char> _bits;//位图其实是一个char类型的vector
};int main()
{bitset<100> bs;bs.set(10);bs.set(11);bs.set(15);cout << bs.find(10) << " ";cout << bs.find(15) << endl;bs.reset(10);cout << bs.find(10) << " ";cout << bs.find(15) << endl;return 0;
}

        运行结果:

3、位图与哈希表的区别

        1、位图在bit为层面上操作,而哈希表在byte层面上操作。

        2、每一个不重复的数据都会在位图中有唯一的位置(即位图不存在哈希冲突),而哈希表需要另外“挂桶"才可解决哈希冲突。

        3、位图面对海量数据时比哈希表更节省空间,但是面对数据量小且特殊时,位图所消耗的空间可能比哈希表大,比如只有4个数据:1,10,100,100000,若用位图则必须开100000/8个char元素。

        4、位图只能映射整形数据,哈希表可以映射多种类型的数据。

4、位图的应用

        比如:给定一百亿个整数,要求查找该数据集中只出现一次的数据。

        思路: 因为位图只能记录两种状态:存在/不存在,所以一张位图显然是很难完成这项要求的,因为无非判断出现2次以上的场景,因此这里需要两张位图。如果一个数据出现了一次,则第一个位图置为1,出现两次则第二个位图置为1,出现更多就不处理了。然后遍历这两种位图,若第一个位图是1,第二个位图是0,则表明该位置对应的数据只出现了一次。


        代码实现:

#define _CRT_SECURE_NO_WARNINGS 1#include <vector>
#include <iostream>
using namespace std;template<size_t N>
class bitset
{
public:bitset(){_bits.resize(N / 8 + 1, 0);//位图的大小和初始化}void set(size_t x){size_t i = x / 8;size_t j = x % 8;_bits[i] |= (1 << j);//或-只要有一个为1结果就为1}void reset(size_t x){size_t i = x / 8;size_t j = x % 8;_bits[i] &= ~(1 << j);//或-只要有一个为0结果就为0}bool find(size_t x){size_t i = x / 8;size_t j = x % 8;return _bits[i] & (1 << j);//_bits[i]为1说明该数据存在}private:vector<char> _bits;//位图其实是一个char类型的vector
};template<size_t N>
class twobitset
{
public:void set(size_t x){//第一次出现  置为0 1if (_bs1.find(x) == false&& _bs2.find(x) == false){_bs2.set(x);}//第二次出现  置为1 0else if (_bs1.find(x) == false&& _bs2.find(x) == true){_bs1.set(x);_bs2.reset(x);}//第三次出现不处理}void Print(){for (size_t i = 0; i <= N; ++i){if (_bs2.find(i)){cout << i << endl;}}}public:bitset<N> _bs1;bitset<N> _bs2;
};int main()
{int a[] = { 6,6,6,3,2,1,7,9,9,7,2,10,12 };twobitset<12> bs;for (auto e : a){bs.set(e);}bs.Print();return 0;
}

        运行结果:

结语

        以上就是关于位图的讲解,位图实际上就是操作bit位的哈希表,实现起来也相对简单。最后希望本文可以给你带来更多的收获,如果本文对你起到了帮助,希望可以动动小指头帮忙点赞👍+关注😎+收藏👌!如果有遗漏或者有误的地方欢迎大家在评论区补充,谢谢大家!! 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Apple Vision Pro应用源码】Vision Pro吸尘器项目源代码

超级有趣Vision Pro 应用 吸尘器项目 这是一个非常有趣的 Vision Pro项目&#xff0c;会让孩子们爱上打扫卫生。 在这里我展示了如何使用 ARKit&#xff1a;头部跟踪、手部跟踪、场景理解加载和播放声音进程冲突使用 MTLBuffers 处理底层网格数据 项目源代码&#xff1a;Git…

动态规划(算法竞赛、蓝桥杯)--状态压缩DP蒙德里安的梦想

1、B站视频链接&#xff1a;E31 状态压缩DP 蒙德里安的梦想_哔哩哔哩_bilibili #include <bits/stdc.h> using namespace std; const int N12,M1<<N; bool st[N];//st[i]存储合并列的状态i是否合法 long long f[N][M];//f[i][j]表示摆放第i列&#xff0c;状态为…

java-ssm-jsp-大学社团管理系统

java-ssm-jsp-大学社团管理系统 获取源码——》公主号&#xff1a;计算机专业毕设大全

PSINS工具箱笔记——函数定义

绘图函数&#xff1a; 时间进度条&#xff1a; timebar&#xff08;用起来简单&#xff09; 姿态转换&#xff1a; 欧拉角、姿态矩阵、等效旋转矩阵、姿态四元数、运载火箭使用的欧拉角之间的转换。 轨迹生成&#xff1a; seg trjsegment(seg, segtype, lasting, w, a, var…

centos上部署k8s

环境准备 四台Linux服务器 主机名 IP 角色 k8s-master-94 192.168.0.94 master k8s-node1-95 192.168.0.95 node1 k8s-node2-96 192.168.0.96 node2 habor 192.168.0.77 镜像仓库 三台机器均执行以下命令&#xff1a; 查看centos版本 [rootlocalhost Work]# cat /…

武汉灰京文化:游戏市场推广与用户增长的成功典范

作为游戏行业的明星企业&#xff0c;武汉灰京文化在市场推广和用户增长方面的成功经验备受瞩目。他们以创造性和独特性的市场营销策略&#xff0c;成功吸引了大量用户。这不仅提高了其游戏的知名度&#xff0c;还为公司带来了持续的增长。这一成功模式不仅对公司自身有益&#…

PaddlePaddle----基于paddlehub的OCR识别

Paddlehub介绍 PaddleHub是一个基于PaddlePaddle深度学习框架开发的预训练模型库和工具集&#xff0c;提供了丰富的功能和模型&#xff0c;包括但不限于以下几种&#xff1a; 1.文本相关功能&#xff1a;包括文本分类、情感分析、文本生成、文本相似度计算等预训练模型和工具。…

政安晨【示例演绎虚拟世界开发】(六):从制作一个对战小游戏开始(Cocos Creator 《击败老大》)(第三段)

在上一篇文章中&#xff0c;我们已经将游戏的场景基本搭建完毕&#xff0c;接下来我们就可以为游戏编写代码并实现相关的核心逻辑了。 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: AI虚拟世界大讲堂 希望政安晨的博客能够对您有所裨益&a…

基于NB-IoT的西红柿基地温湿度监测系统

总体硬件架构 在西红柿种植园内&#xff0c;我们为每株作物分配RFID标签&#xff0c;以便在每次照顾作物后记录其生长状况、施肥和灌溉等信息。这些数据将上传至云端&#xff0c;便于用户在线实时监控作物生长情况。 为了确保温湿度的精确控制&#xff0c;我们在作物棚内每隔3米…

appium2的一些配置

appium-desktop不再维护之后&#xff0c;需要使用appium2。 1、安装appium2 命令行输入npm i -g appium。安装之后输入appium或者appium-server即可启动appium 2、安装安卓/ios的驱动 安卓&#xff1a;appium driver install uiautomator2 iOS&#xff1a;appium driver i…

算法沉淀——贪心算法一(leetcode真题剖析)

算法沉淀——贪心算法一 01.柠檬水找零02.将数组和减半的最少操作次数03.最大数04.摆动序列 贪心算法&#xff08;Greedy Algorithm&#xff09;是一种基于贪心策略的优化算法&#xff0c;它通常用于求解最优化问题&#xff0c;每一步都选择当前状态下的最优解&#xff0c;以期…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:TapGesture)

支持单击、双击和多次点击事件的识别。 说明&#xff1a; 从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 接口 TapGesture(value?: { count?: number, fingers?: number }) 参数&#xff1a; 参数名称参数类型必填参…

sql多表运用 12.3

肖SIR__数据库之多表运用__12.3 数据库之多表运用 CREATE table dept(dept1 VARCHAR(6),dept_name VARCHAR(20)) default charsetutf8; INSERT into dept VALUES (101,财务); INSERT into dept VALUES (102,销售); INSERT into dept VALUES (103,IT技术); INSERT into dep…

前端工具网站合集(持续更新)

综合类网站 那些免费的砖 统计推荐免费工具网站 那些免费的砖 - 优雅地白嫖各种免费资源 (thosefree.com)https://www.thosefree.com/ CSS样式网站 毒蘑菇-配色 CSS 配色&#xff0c;阴影网站 一个好用的配色网站! 毒蘑菇 - 配色 (dumogu.top)https://color.dumogu.top/ …

如何使用Minitab计算MSA数据

1.1 步骤一 将数据复制进Minitab数据区 1.2 步骤二 按图示选择 1.3 步骤三 按图示选择&#xff0c;测量数据那列根据自己填入的数据而定 1.4 数据 评价中的重要指标为可区分类别数&#xff08;通常需大于10&#xff09;&#xff0c;合计量具R&R&#xff08;通常需小于10&am…

alibabacloud学习笔记07(小滴课堂)

讲解Sentinel自定义异常降级-新旧版本差异 讲解新版Sentinel自定义异常数据开发实战 如果我们都使用原生的报错&#xff0c;我们就无法得到具体的报错信息。 所以我们要自定义异常返回的数据提示&#xff1a; 实现BlockExceptionHandler并且重写handle方法&#xff1a; 使用F…

Jupyter如何开启Debug调试功能

由于需要对算子做远程调试功能&#xff0c;需要在jupyter中开启远程断点调试功能&#xff0c;特此记录。 本文写作时用到的系统是Ubuntu22&#xff0c;Python的版本是3.8. 首先&#xff0c;创建虚拟环境。 python -m venv venv source venv/bin/activate接着&#xff0c;安装…

【教程】无法验证app需要互联网连接以验证是否信任开发者

摘要 本文将探讨在使用苹果App时遇到无法验证开发者的情况&#xff0c;以及用户可以采取的解决方案。通过检查网络连接、重新操作、验证描述文件等方式来解决无法验证开发者的问题。同时&#xff0c;还介绍了开发者信任设置的步骤&#xff0c;以及使用appuploader工具进行安装…

Vue点击切换组件颜色

例如我有一个这样的组件&#xff0c;我希望在点击组件之后由蓝色变成橙色 先把原来的代码附上(简化掉了叉号&#xff09;&#xff1a; <div v-for"(item, index) in words" :key"index" class"scrollbar-demo-item"><span>{{ item …

python入门必会的助手函数:dir()函数

今天我们来看一个非常重要的函数&#xff1a;dir() 中文说明&#xff1a;不带参数时&#xff0c;返回当前范围内的变量、方法和定义的类型列表&#xff1b;带参数时&#xff0c;返回参数的属性、方法列表。如果参数包含方法__dir__()&#xff0c;该方法将被调用。如果参数不包…