C++位图的实现与详解

news2024/11/17 0:37:01

1.位图概念

在讲解位图之前我们先来看一道很经典的面试题。

给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。
我们有以下两种种解决方法:

1. 遍历,时间复杂度O(N)。(太慢)

2. 排序(O(NlogN)),利用二分查找: logN。

深入分析:解题思路2是否可行,我们先算算40亿个数据大概需要多少内存。1G=1024MB=1024*1024KB=1024*1024*1024Byte约等于10亿多Byte那么40亿个整数约等于16G,说明40亿个数是无法直接放到内存中的,只能放到硬盘文件中。而二分查找只能对内存数组中的有序数据进行查找。

其实我们并不需要开如此大的空间,我们只需要知道这个数据在或者不在,刚好是两种状态,那么可以使用一个二进制比特位来代表数据是否存在的信息,如果二进制比特位为1,代表存在,为0代表不存在。

位图概念

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

2.位图的实现

namespace bit
{
	template<size_t N>
	class bitset
	{
	public:

	private:
		std::vector<int> _bs;
	};
}

现在我们要做的是如何修改x 对应的位置比特位。(如下)

i = x / 32    得到 x在vector中的第 i 个整形数据。

a = x % 32 得到 x在第 i 位的第 a位。

namespace bit
{
	template<size_t N>
	class bitset
	{
	public:
		bitset()
		{
			_bs.resize(N / 32 + 1);
		}

		void set(size_t x)//表示x 存在
		{
			int i = x / 32;
			int a = x % 32;
            
			_bs[i] |= (1 << a);
		}

		void reset(size_t x)//表示x 不存在
		{
			int i = x / 32;
			int a = x % 32;

			_bs[i] &= (~(1 << a));
		}

		//x处映射的值是1 返回真
		//x处映射的值是0 返回假
		bool rest(size_t x)
		{
			int i = x / 32;
			int a = x % 32;

			return _bs[i] & (1 << a);
		}

	private:
		std::vector<int> _bs;
	};
}
int main()
{
	bit::bitset<100> bs;
	bs.set(32);
	bs.reset(32);
	bs.set(33);
	cout<<bs.rest(31)<<endl;
	cout<<bs.rest(32)<<endl;
	cout<<bs.rest(33)<<endl;
	cout<<bs.rest(34)<<endl;
	cout<<bs.rest(35)<<endl;

	return 0;
}

测试结果如下: 

3.bitset的使用

如果要开大量空间我们可以这样

但是库里面是开不出来的

因为我们自己实现的底层使用的是vector 开空间是在堆上面,而库里面底层实现是静态数组,所以开不出来。

可以看到我们无论开多大的空间他本身所占的内存都是16因为我们的核心空间都开在堆上的。

库里面就不一样了如下:

大家使用库里面bitset的就要小心使用。

解决办法如下:

位图的优缺点:

  • 优点:增删查改快,节省空间
  • 缺点:只能适用整形

接下来看几道关于位图的题目:

  • 给定40亿个整数,设计算法找到只出现一次的整数。

我们可以用

00:表示0次

01:表示1次

10:表示2次及以上

void testbitset(vector<int>& arr)
{
	bit::bitset<-1> bs1;
	bit::bitset<-1> bs2;
	for (auto& e : arr)
	{
		if (!bs1.rest(e) && !bs2.rest(e))//00->01
		{
			bs2.set(e);
		}
		else if(!bs1.rest(e) && bs2.rest(e))//01->10
		{
			bs2.reset(e);
			bs1.set(e);//10
		}
		else//10->11
		{
			bs2.set(e);
		}
	}

	for (int e = 0; e < 100; e++)
	{
		if (!bs1.rest(e) && bs2.rest(e))
		{
			//出现一次
			cout << "1->:" << e << endl;
		}
		else if (bs1.rest(e) && !bs2.rest(e))
		{
			//出现两次
			cout << "2->:" << e << endl;
		}
		else if(bs1.rest(e) && bs2.rest(e))
		{
			//出现三次及以上
			cout << "3->:" << e << endl;
		}
	}
}



int main()
{
	vector<int> v1({0, 0, 1, 1, 2, 2, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6});
	testbitset(v1);
}

感谢大家的观看!

 

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

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

相关文章

如何在红米手机中恢复已删除的照片?(6 种方式可供选择)

凭借出色的相机和实惠的价格&#xff0c;小米红米系列已成为全球知名品牌。但是&#xff0c;最近有些人抱怨他们在 红米设备上丢失了许多珍贵的图片或视频&#xff0c;并希望弄清楚如何从小米手机恢复已删除的照片。好吧&#xff0c;在小米设备上恢复已删除的视频/照片并不难。…

RK3576芯片在智能家居里中型智慧屏产品的应用方案分析

智能家居在近年来得到了快速发展&#xff0c;AI技术不断发展&#xff0c;人机交互十分成熟&#xff0c;各种家电也都迎来了智能化浪潮&#xff0c;智能家居为人们提供了优秀的产品体验&#xff0c;受到主流消费者的青睐&#xff0c;智能家居里的中型智慧屏产品也随之兴起。 瑞芯…

HTTrack

--不破不立 HTTrack 是一个免费开源的网站离线浏览器。通过它可以将整个网站下载到本地的某个目录&#xff0c;包括 html、图片和脚本以及样式文件&#xff0c;并对其中的链接进行重构以便于在本地进行浏览。 1.官网下载地址&#xff1a;https://www.httrack.com/page/2/en/in…

通信工程学习:什么是FMC固定移动融合

FMC&#xff1a;固定移动融合 FMC固定移动融合&#xff0c;即Fixed Mobile Convergence&#xff08;固定移动网络融合&#xff09;&#xff0c;是指通过固定网络与移动网络之间的融通、合作&#xff0c;实现全业务及融合业务的经营。这一技术旨在打破传统固定网络和移动网络之间…

设计模式-面试题(工厂方法模式、策略模式和责任链模式)

开闭原则&#xff1a;扩展开放、修改关闭 工厂设计模式&#xff1a;解耦 简单工厂模式 CoffeeStore和SimpleCoffeeFactory的耦合、SimpleCoffeeFactory和Coffee的耦合 后续如果再加新品种的咖啡&#xff0c;需要修改SimpleCoffeeFactory&#xff0c;这样就违反了开闭原则 简单…

探探我对测试开发的看法?

测试开发岗位主要负责确保软件的可用性和稳定性。 ● 可用性不仅包括功能的正常使用&#xff0c;还涵盖了软件在不同环境下的兼容性&#xff0c;如各种网络环境、不同 CPU 核心环境以及多样化的移动端设备等。 ● 稳定性方面我的理解是&#xff0c;测试人员不仅要从用户角度评判…

Mac无法安装软件怎么解决?mac安装软件提示无法验证开发者怎么办

在使用 macOS 系统时&#xff0c;你可能会遇到一个常见的问题&#xff1a;当你尝试安装或打开某些应用程序时&#xff0c;系统会弹出一个警告&#xff0c;提示“无法验证开发者”。出现这个提示导致自己无法去进行程序安装&#xff0c;接下来我们就来看看如何解决此问题的方法吧…

windows下载nvm并使用合集

下载nvm之前是要把node卸载的&#xff0c;不然会安装不成功 下面我先把nvm地址放上NVM下载 - NVM中文网 按照步骤按照完了一会可以使用一下命令来检查是否安装成功 nvm 安装成功后会出来版本号 下面开始安装node版本&#xff0c;很多朋友一上来直接下载node会报错 问题分析 …

【C++】_list常用方法解析及模拟实现

相信自己的力量&#xff0c;只要对自己始终保持信心&#xff0c;尽自己最大努力去完成任何事&#xff0c;就算事情最终结果是失败了&#xff0c;努力了也不留遗憾。&#x1f493;&#x1f493;&#x1f493; 目录 ✨说在前面 &#x1f34b;知识点一&#xff1a;什么是list&…

【EST】:Pt/ZrO2单原子催化剂

摘要&#xff1a;制备稳定的单原子催化剂一直是环境催化领域去除各种污染物的研究热点&#xff0c;但在提高反应性和稳定性方面仍存在挑战。在此&#xff0c;通过在锆氧化物负载的铂催化剂&#xff08;Pt–Na/ZrO2&#xff09;中简单掺杂碱金属&#xff0c;成功制备了与碱金属通…

【C++初阶】:C++入门,引用概念及其性质

文章目录 一、引用的概念二、引用的语法规则1、引用特性2、常引用 二、引用的使用场景1. 引用做参数2. 引用做返回值 三、引用和指针的区别 一、引用的概念 首先明确一下&#xff0c;引用不是定义一个新的变量&#xff0c;而是给已经存在的变量起一个别名&#xff0c;变量和他…

相机内存卡格式化了照片怎么恢复?格式化恢复详解

摄影爱好者们都知道&#xff0c;相机内存卡是记录我们美好瞬间的重要媒介。然而&#xff0c;在使用过程中&#xff0c;有时我们会因操作不当或设备故障&#xff0c;不小心格式化了内存卡&#xff0c;从而导致珍贵的照片丢失。面对这种情况&#xff0c;我们该如何恢复这些被格式…

贪吃蛇项目实现(C语言)——附源码

前言 贪吃蛇是一款十分经典的游戏&#xff0c;其通过控制贪吃蛇的上下左右移动来吃食物&#xff0c;延长自己的身体&#xff0c;也会因为撞到墙体和自身而死亡。下面我们通过C语言来实现贪吃蛇。 1.技术要点 C语言枚举&#xff0c;结构体&#xff0c;链表&#xff0c;动态内…

内网中的RDP利用

学习参考 https://www.freebuf.com/articles/network/276242.html能跟着实操的都实操一下。熟悉一些命令&#xff0c;过程。 实验环境&#xff1a;win2008&#xff0c;192.168.72.139 两个用户&#xff1a; administrator&#xff0c;shizuru RDP服务 确定/开启 RDP服务确…

力扣第79题 单词搜索

前言 记录一下刷题历程 力扣第79题 单词搜索 单词搜索 原题目&#xff1a;给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通过相邻…

解决ubuntu安装modelsim20.1 32位库依赖失败问题(附简易安装方法)

先说方法&#xff1a;不用管&#xff0c;直接继续安装软件就行。 注意&#xff0c;选中 libgtk-3-0t64:i386 而非 libgtk-3-0:i386 注意&#xff0c;选中 libcanberra0t64:i386 而非 libcanberra0:i386 注意&#xff0c;选中 libpng16-16t64:i386 而非 libpng16-16:i386 注意&…

白盒测试_学习总结

目录 一、白盒测试的概念理解 二、白盒测试的分类 1、静态分析 2、动态分析 &#xff08;1&#xff09;逻辑覆盖测试 a、语句覆盖 b、判定覆盖 c、条件覆盖 d、判定条件覆盖 e、条件组合覆盖 f、路径覆盖 &#xff08;2&#xff09;基本路径测试法 3、总结 一、白盒…

Arduino基础入门学习——BH1750(GY-302)+ LED模拟自动路灯的实现

BH1750&#xff08;GY-302&#xff09; LED 一、前言三、准备工作四、程序代码五、运行结果六、结束语 一、前言 相信很多人都见过一种路灯&#xff0c;白天的时候它是不亮的&#xff0c;等到了晚上环境变暗时就开始它的照明工作了&#xff0c;不了解的人可能认为是人为操纵它工…

如何编写Prompt,利用AI高效生成图表——图表狐(FoxChart)指南

在数据可视化领域&#xff0c;图表是数据的重要表达方式。为了让更多人能够轻松高校地生成美观、专业的图表&#xff0c;图表狐(FoxChart)应用而生。然而&#xff0c;要想充分发挥AI的潜力&#xff0c;编写合适的Prompt至关重要。本文介绍一些编写Prompt的原则&#xff0c;帮助…

代码随想录算法训练营第39天|198.打家劫舍、 213.打家劫舍II、337. 打家劫舍 III

目录 198.打家劫舍1、题目描述2、思路3、code4、复杂度分析 213.打家劫舍II1、题目描述2、思路3、code4、复杂度分析 337. 打家劫舍 III1、题目描述2、思路3、code4、复杂度分析 198.打家劫舍 题目链接&#xff1a;添加链接描述 1、题目描述 你是一个专业的小偷&#xff0c;计…