C++_位图

news2024/11/18 11:21:15

       

目录

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 1
		if (_bs1.find(x) == false
			&& _bs2.find(x) == false)
		{
			_bs2.set(x);
		}
		//第二次出现  置为1 0
		else 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.coloradmin.cn/o/1492326.html

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

相关文章

pdf属性修改教程 如何修改pdf 属性?

PDF&#xff08;Portable Document Format&#xff09;是一种广泛使用的文件格式&#xff0c;用于呈现文档&#xff0c;包括文本、图像、图形和其他元素。PDF文件的一个特点是其属性&#xff0c;这些属性包括文件的创建日期、修改日期、作者、标题、主题、关键词等。这些属性在…

WordPress建站入门教程:忘记数据库名称、用户名和密码了怎么办?

有时候我们需要进入phpMyAdmin管理一些数据库&#xff0c;但是登录phpMyAdmin时却需要我们输入数据库的用户名和密码&#xff0c;但是我们不记得了应该怎么办呢&#xff1f; 其实&#xff0c;我们只需要进入WordPress网站根目录找到并打开wp-config.php文件&#xff0c;就可以…

基于Google Vertex AI 和 Llama 2进行RLHF训练和评估

Reinforcement Learning from Human Feedback 基于Google Vertex AI 和 Llama 2进行RLHF训练和评估 课程地址&#xff1a;https://www.deeplearning.ai/short-courses/reinforcement-learning-from-human-feedback/ Topic: Get a conceptual understanding of Reinforcemen…

基于肤色模型和中值滤波的手部检测算法FPGA实现,包括tb测试文件和MATLAB辅助验证

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 肤色模型建立与应用 4.2 中值滤波器的运用 5.算法完整程序工程 1.算法运行效果图预览 RTL图&#xff1a; 仿真图&#xff1a; 导入到matlab显示效果如下&#xff1a; 2.算法运行软件版…

【Azure 架构师学习笔记】- Azure Service Endpoint

本文属于【Azure 架构师学习笔记】系列。 前言 在做Azure 架构时&#xff0c;经常会被问到Service Endpoint这个点&#xff0c;那么这篇文章来介绍一下Service Endpoint&#xff08;SE&#xff09;。 Azure Service Endpoint 首先它是一个专用通道&#xff0c;在Azure 资源之…

DOM破坏BurpSuite学院(Up升级版[其实就是代码变多了])

首先我们先看一个案例 location.hash是一个锚点获取URL的注释后面的东西 打断点&#xff1a; 可以看到传值如下&#xff1a; 循环利用removeAttribute去除掉 但是结果&#xff0c;本改被移除的onerror属性逃逸出来了&#xff0c;把一个正常的属性删掉了&#xff1f;&#xff1f…

day04-Maven

一、初识 Maven Maven 是 Apache 旗下的一个开源项目&#xff0c;是一款用于管理和构建 java 项目的工具。 官网&#xff1a;https://maven.apache.org/ Maven的作用 依赖管理&#xff08;方便快捷的管理项目依赖的资源(jar包)&#xff0c;避免版本冲突问题&#xff09;统一项目…

【开源】JAVA+Vue.js实现独居老人物资配送系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 查询社区4.2 新增物资4.3 查询物资4.4 查询物资配送4.5 新增物资配送 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的独居老人物资配送系统&#xff0c;包含了社区档案、…

对象得定义与使用(动力节点老杜)

对象思想 1.什么是面向过程&#xff0c;什么是面向对象&#xff1f; 换而言之&#xff0c;面向对象思想实际就是将整体分成一个个独立的单元&#xff0c;每个单元都有自己得任务和属性&#xff0c;所有单元结合在一起完成一个整体。如果某个单元出现了问题还可以及时处理&…

博客等级怎么查看?博客等级怎么快速上升?博客等级升级要求是什么?如何增加博客等级上升的积分?等级权益有什么?

博客等级怎么查看&#xff1f;博客等级怎么快速上升&#xff1f;博客等级升级要求是什么&#xff1f;如何增加博客等级上升的积分&#xff1f;等级权益有什么&#xff1f; 一、博客等级怎么查看&#xff1f;二、博客等级怎么快速上升&#xff1f;2.1 博客等级升级要求是什么&am…

矩阵错题本

《1800》 1 逗号中间全是0啊 2 代入转置即可证明 3 只是凭借感觉 4 线性代数真的是细节狂魔 经过若干次初等变换&#xff0c;秩相等 5 P1的逆为啥是P1 6 越排后的矩阵变换越排前 对角线矩阵的逆矩阵&#xff0c;除了对角线元素&#xff0c;全换号 7 根据题设给出来的矩阵求…

[Angular 基础] - routing 路由(下)

[Angular 基础] - routing 路由(下) 之前部分 Angular 笔记&#xff1a; [Angular 基础] - 自定义指令&#xff0c;深入学习 directive [Angular 基础] - service 服务 [Angular 基础] - routing 路由(上) 使用 route 书接上回&#xff0c;继续折腾 routing 按照最初的 wi…

计算机设计大赛 深度学习的动物识别

文章目录 0 前言1 背景2 算法原理2.1 动物识别方法概况2.2 常用的网络模型2.2.1 B-CNN2.2.2 SSD 3 SSD动物目标检测流程4 实现效果5 部分相关代码5.1 数据预处理5.2 构建卷积神经网络5.3 tensorflow计算图可视化5.4 网络模型训练5.5 对猫狗图像进行2分类 6 最后 0 前言 &#…

阿里云打响“算力平价”第一枪

大数据产业创新服务媒体 ——聚焦数据 改变商业 2月29日&#xff0c;阿里云宣布了史上最大力度的一次降价&#xff0c;平均降价幅度超过20%&#xff0c;最高降幅达55%。通过此次降价&#xff0c;阿里云的核心云计算产品价格都击穿了全网最低价。 这次降价&#xff0c;涉及100多…

HTML静态网页成品作业(HTML+CSS)——我的家乡北京网页设计制作(7个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示1、首页2、子页13、子页24、子页35、子页46、子页57、子页6 三、代码目录四、网站代码HTML部分代码CSS部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0…

web学习笔记(二十五)BOM

目录 1.BOM概述 1.1什么是BOM 1.2BOM的构成 2.windom常用属性汇总 3.window常用方法汇总 4.window对象常见事件汇总 5.this总结&#xff1a; 1.BOM概述 1.1什么是BOM BOM(Browser Object Model)就是浏览器对象模型(整个浏览器)&#xff0c;他的核心对象是window,BOM缺…

探索 PostgreSQL 的高级数据类型 - 第 1 部分

数组和枚举 PostgreSQL 因其可扩展性和多功能性而备受欢迎&#xff0c;除了传统的整数和字符串之外&#xff0c;它还提供了多种数据类型。其中&#xff0c;包括数组和枚举&#xff0c;其为开发者提供了高级的数据建模能力。本文中&#xff0c;我们将深入研究这些复杂的数据类型…

CSS常用五类选择器,附面试题

学习路线 第一阶段&#xff1a;网页制作 HTML&#xff1a;常用标签&#xff0c;锚点&#xff0c;列表标签&#xff0c;表单标签&#xff0c;表格标签&#xff0c;标签分类&#xff0c;标签语义化&#xff0c;注释&#xff0c;字符实体 CSS&#xff1a;CSS介绍&#xff0c;全局…

mac报错:zsh: command not found: npm

1、问题概述&#xff1f; 在mac系统中使用npm命令的时候&#xff0c;mac os报错提示&#xff1a; zsh: command not found: npm 一般出现发这种情况的原因时没有安装npm,而npm这命令时集成在nodejs中的&#xff0c;所以安装nodejs就可以了。 2、解决办法 本质就是需要安装…

论文笔记:Code Llama: Open Foundation Models for Code

导语 Code Llama是开源模型Llama 2在代码领域的一个专有模型&#xff0c;作者通过在代码数据集上进行进一步训练得到了了适用于该领域的专有模型&#xff0c;并在测试基准中超过了同等参数规模的其他公开模型。 链接&#xff1a;https://arxiv.org/abs/2308.12950机构&#x…