C++位图

news2024/9/20 16:45:19

位图

位图

文章目录

  • 位图
      • set
      • Reset
      • Test
      • 整体代码
      • 位图应用

给定40亿个不重复、没排序的无符号整数,再给一个无符号整数,如何快速判断一个数是否在这40亿个数中???

首先想到的是归并排序+二分查找。排序可以排,但是通过文件指针去查找会很慢。

其次是set和哈希表。set自动可以排序且在红黑树中查找速度也很快。但要把40亿个整数加上红黑树的节点(三叉链外加颜色)放进内存里,内存明显不够,不可取;哈希表同样是把40亿个整数外加节点放进内存里,内存明显不够,也不可取。

那么既然要把40亿个整形放进内存里,判断在或者不在,用1标记在用0标记不在。1个比特位就能满足标记1或0。用直接定址法。1个char类型-1个字节-8个比特位。无符号整数有42亿9千万个,全部用比特位来代表的话就只需要512M。这种方法可行。用char类型来开辟空间,那么第一个char就能存储07,第二个char就能存储815,第三个。。。。。。

image-20230422112358980

set

把要set的值通过/8找到对应的char(小位图),再通过%8找到对应的位置,把该位置标记成1即为该值存在于这堆数中

		void Set(size_t x)//把x值对应的标记为置为1
		{
			//计算x位于哪一个char上
		//	size_t i = x / 8;
			size_t i=x >> 3;//相当于x/8
			//计算x位于哪个bit上
			size_t j = x % 8;
			_bit[i] |= (1 << j);
		}

位图set

Reset

把要Reset的值通过/8找到对应的char(小位图),再通过%8找到对应的位置,把该位置标记成0即把该值从这堆数中抹去

void ReSet(size_t x)//把x值对应的标记置为0
		{
			//计算x位于哪一个char上
			//size_t i = x / 8;
			size_t i = x >> 3;//相当于x/8
			//计算x位于哪个bit上
			size_t j = x % 8;
			_bit[i] &= (~(1 << j));
		}

位图reset

Test

把要Reset的值通过/8找到对应的char(小位图),再通过%8找到对应的位置。先按位取反原来的位图,再把原来的位图与取反的位图按位与,若存在1则为非0,为真返回true;若不存在则没有1全0,为假,返回false;

		bool Test(size_t x)//判断x是否在这堆数里面
		{
			//计算x位于哪一个char上
			//size_t i = x / 8;
			size_t i = x >> 3;//相当于x/8
			//计算x位于哪个bit上
			size_t j = x % 8;
			return _bit[i] & (1 << j);
		}

位图test1

位图test2

整体代码

	template<size_t N>//用非类型模板参数---N为要往位图里存储多少个数
	class  BitSet
	{public:
		BitSet()
		{
            //_bit.resize(N >> 3) + 1);
			_bit.resize(N / 8 + 1);//多开一个
		}

		void Set(size_t x)//把x值对应的标记为置为1
		{
			//计算x位于哪一个char上
		//	size_t i = x / 8;
			size_t i=x >> 3;//相当于x/8
			//计算x位于哪个bit上
			size_t j = x % 8;
			_bit[i] |= (1 << j);
		}

		void ReSet(size_t x)//把x值对应的标记置为0
		{
			//计算x位于哪一个char上
			//size_t i = x / 8;
			size_t i = x >> 3;//相当于x/8
			//计算x位于哪个bit上
			size_t j = x % 8;
			_bit[i] &= (~(1 << j));
		}

		bool Test(size_t x)//判断x是否在这堆数里面
		{
			//计算x位于哪一个char上
			//size_t i = x / 8;
			size_t i = x >> 3;//相当于x/8
			//计算x位于哪个bit上
			size_t j = x % 8;
			return _bit[i] & (1 << j);
		}

		vector<char> _bit;
	};

当开最大的整形数时,内存也只占512M左右

image-20230423160349779

库里面也有

bitset
image-20230423160904693

位图应用

  1. 快速查找某个数据是否在一个集合中
  2. 排序+去重
  3. 求两个集合的交集、并集等
  4. 操作系统中磁盘块标记
给两个文件,分别有100亿个整数,我只有1G内存,如何找到两个文件的交集???

把文件1的数据放进位图1,把文件2的数据放进位图2,然后逐个遍历位图1的数据同时遍历位图2。当两个位图的数据的标记位都是1时,说明该数据即存在文件1也存在文件2,这个数据就是两个文件的交集。逐个遍历两个位图,找出相同的数据即可。

image-20230423183904153

//测试
void testBitset()
	{
		BitSet<100> bs1;
		BitSet<100> bs2;
		int path1[] = { 1,2,3,4,5 };
		int path2[] = { 1,3,5 };

		for (auto e : path1)
		{
			bs1.Set(e);
		}

		for (auto e : path2)
		{
			bs2.Set(e);
		}

		for (size_t i = 0; i < 100; i++)
		{
			if (bs1.Test(i) && bs2.Test(i))//11
			{
				cout << i << endl;
			}
		}
		}
一个文件有100亿个int,1G内存,设计算法找出次数不超过2次的所有整数

用两个位图来记录出现的数据次数。出现0次就是00,出现1次就是01,出现2次就是10,出现3次或以上就是11。记录两个位图标记位为01,10的数据。

浅搓了个代码

template<size_t N>
	class twoBitset
	{
	public:
		void Set(size_t x)
		{

			if (!bs1.Test(x) && !bs2.Test(x))//两个位图都是0---数据出现0次
			{//00->01
				bs2.Set(x);
			}
			else if (!bs1.Test(x) && bs2.Test(x))//第一个位图是1,第二个位图是0---数据出现1次
			{//01->10
				bs1.Set(x);
				bs2.ReSet(x);
			}
			else //两个位图都是1---数据出现2次
			{//10->11
				
				bs2.Set(x);
			}
			//else//出现3次及以上
			//{
			//	break;
			//}
		}

		void  Printones()
		{
			for (size_t i = 0; i < N; i++)
			{
				if (!bs1.Test(i) && bs2.Test(i))//01
				{
					cout << i << endl;
				}
				else if (bs1.Test(i) && !bs2.Test(i))//10
				{
					cout  << i << endl;
				}
				


			}

		}
	private:
		BitSet<N> bs1;
		BitSet<N> bs2;

	};
给一个超过100G的log file,log中存着IP地址,设计算法找到出现次数最多的IP地址

先通过哈希函数哈希切分这个100G的文件,然后冲突的IP地址放进同一个小文件里;接着用map依次统计每个文件的相同IP的次数,统计完一个clear掉map统计下一个。

此时小文件有两种情况,一是小文件里大部分冲突的IP都是重复的,此时直接用map可以统计次数。二是小文件里大部分冲突的IP都是不重复的,此时用map统计不下,使用mp的insert时会插入失败,即没内存去new节点了,new失败会抛异常,这时需要换个哈希函数,对这个小文件再次通过哈希切分,分成更细小的文件。

image-20230423213026093

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

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

相关文章

【计算机组成原理】第三章 存储系统

文章目录 知识体系3.1 存储器概述3.1.1 存储器的分类3.1.2 存储器的性能指标3.1.3 多级层次的存储系统 3.2 主存储器3.2.1 SRAM芯片和DRAM芯片3.2.2 只读存储器3.2.3 主存储器的基本组成3.2.4 多模块存储器 3.3 主存储器与CPU的连接3.3.1 连接原理3.3.2 主存容量的扩展3.3.3 存…

指定GPU运行python程序

一、命令行运行python程序时 1、首先查看哪些GPU空闲&#xff0c;nvidia-smi显示当前GPU使用情况。 nvidia-smiGPU&#xff1a;编号&#xff0c;这里是0和1 Fan&#xff1a;风扇转速&#xff0c;在0到100%之间变动&#xff0c;第一个是29% Name&#xff1a;显卡名&#xff…

布署到centos7.9时,ModuleNotFoundError: No module named ‘_sqlite3‘

先下载编译sqlite3 wget http://www.sqlite.org/sqlite-3.5.6.tar.gz cd sqlite-3.5.6 ./configure --disable-tcl make && make install 注意add LIBDIR to the ‘LD_LIBRARY_PATH’ environment variable&#xff0c;这是sqlite建议添加环境变量。 所以: echo expor…

「C/C++」C/C++异常处理

博客主页&#xff1a;何曾参静谧的博客 文章专栏&#xff1a;「C/C」C/C学习 目录 相关术语一、C语言中的异常处理1.返回值来传递错误信息2.使用标准库函数对异常进行处理&#xff08;不推荐&#xff09;3.使用全局变量来记录错误信息(不推荐) 二、C中的异常处理1.try{}catch()…

内外部函数静态变量全局变量

1、函数&#xff08;封装、复用&#xff09; 功能性&#xff1a;最基本的特性&#xff1b; 扩展性&#xff1a;对于时刻变化的需求易于扩展&#xff1b; 维护性&#xff1a;对于时刻变化的需求易于维护&#xff0c;易于编码变更&#xff1b; 封装性&#xff1a;不要把所有的代…

G1回收器:区域化分代式

G1回收器概述 既然我们己经有了前面几个强大的GC,为什么还要发布Garbage First(G1)GC? 原因就在于应用程序所应对的业务越来越庞大、复杂&#xff0c;用户越来越多&#xff0c;没有GC就不能保证应用程序正常进行&#xff0c;而经常造成STW的GC又跟不上实际的需求&#xff0c…

Python 实验四 常用数据结构(1)

1.从键盘输入一个正整数列表&#xff0c;以一1结束&#xff0c;分别计算列表中奇数和偶数的和。 n int(input("请输入一个正整数&#xff1a;")) list [] while n ! -1:list.append(n)n int(input("请输入一个正整数&#xff1a;")) else:print("…

Linux下C/C++实现(网络流量分析-NTA)

网络流量分析&#xff08;NTA - Network Traffic Analysis) 就是捕捉网络中流动的数据包&#xff0c;并通过查看包内部数据以及进行相关的协议、流量、分析、统计等&#xff0c;协助发现网络运行过程中出现的问题。通过监控和分析网络环境中的流量&#xff0c;来判断流量是用在…

electron编译环境搭建和第一个桌面应用例子

前言 Electron是基于Chromium和Node.js实现的&#xff0c;所以开发人员所需要使用到的前端技术主要包括以下方面&#xff1a; 1、Html、CSS、JavaScript、ES6 2、前端开发工具Vue、Angular、React等的一种 3、其他网络、缓存、通讯、系统、跟踪等前端技术 4、对Vscode编辑…

SpringCloud --- 认识微服务、服务拆分和远程调用

一、认识微服务 随着互联网行业的发展&#xff0c;对服务的要求也越来越高&#xff0c;服务架构也从单体架构逐渐演变为现在流行的微服务架构。这些架构之间有怎样的差别呢&#xff1f; 1.1、单体架构 单体架构&#xff1a;将业务的所有功能集中在一个项目中开发&#xff0c;…

C++学习(day5)

文章目录 一. 静态成员变量和函数(static)1. 静态成员变量2. 静态成员函数 二. 类的继承&#xff08;inhert&#xff09;1. 继承2. 继承的作用3. 一个类B继承类A4. 继承格式5. 子类会继承父类的所有成员6. 当父子类中出现同名的成员时7. **继承中构造函数和析构函数调用顺序**8…

反垃圾邮件产品测试评价方法示意图

声明 本文是学习信息安全技术 反垃圾邮件产品技术要求和测试评价方法. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 反垃圾邮件产品测试评价方法 测试环境 反垃圾邮件产品的典型测试环境如图1所示。 图1 反垃圾邮件产品典型测试环境示意图 测试设…

快速识别 SLI 指标的方法:VALET

SLI&#xff0c;Service Level Indicator&#xff0c;服务等级指标&#xff0c;其实就是我们选择哪些指标来衡量我们的稳定性。而 SLO&#xff0c;Service Level Objective&#xff0c;服务等级目标&#xff0c;指的就是我们设定的稳定性目标&#xff0c;比如“几个 9”这样的目…

Android音视频开发-OpenGL ES正交投影实现方法

本文实例为大家分享了OpenGL ES正交投影展示的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下 绘制正方形 在最开始绘制的六边形里面好像看起来挺容易的&#xff0c;也没有出现什么问题&#xff0c;接下来不妨忘记前面绘制六边形的代码&#xff0c;让我们按照自己的…

设计模式——组件协作模式之模板方法模式

文章目录 前言一、“组件协作” 模式二、模板方法模式1、动机2、源码分析讲解①、结构化软件设计②、面向对象软件设计 三、模板方法模式定义四、结构要点总结 前言 一、“组件协作” 模式 现代软件专业分工之后的第一个结果是 “框架与应用程序的划分”&#xff0c;“组件协作…

部署LVS-NAT群集实验

一、 实验准备 负载调度器&#xff1a;内网关 ens33&#xff1a;192.168.109.12&#xff0c;外网关 ens37&#xff1a;12.0.0.1外网 Web节点服务器1&#xff1a;192.168.109.13 Web节点服务器2&#xff1a;192.168.109.14 NFS服务器&#xff1a;192.168.109.11 客户端&#xf…

C#基础学习--其他主题

目录 概述 字符串 使用StringBuilder类 把字符串解析为数据值 关于可空类型的更多内容 为可空类型赋值 使用空接合运算符 Main方法 文档注释 嵌套类型 析构函数和dispose模式 概述 再本章中会讲解一些重要的杂项知识 字符串 字符串是Unicode字符串数组 字符串是不可…

ISO-27145故障诊断说明

ISO-27145故障诊断说明 2.1 27145目录说明 ISO27145-1: 这里边介绍的是一般信息和用例定义&#xff1b; ISO27145-2: 这里边介绍的是与排放相关的通用数据规则&#xff0c;用于查询&#xff1b; ISO27145-3: 这里边主要介绍了支持的服务 12服务 14服务 19服务 22服务 31服务&…

【移动端网页布局】移动端网页布局基础概念 ⑧ ( 移动端页面布局方案 | 单独制作的移动端页面 - 主流 | 响应式页面兼容移动端 - 开发难度较大 )

文章目录 一、移动端页面布局方案1、单独制作的移动端页面2、响应式页面兼容移动端 一、移动端页面布局方案 移动端页面方案 : 单独制作的移动端页面 : 主流开发方案 , PC 端 与 移动端 访问的是不同的页面 , 目前的 京东 / 淘宝 等电商网站移动端页面采取的该方案 ;响应式页面…

高效编程----VSCode+ChatGPT插件

VSCode中使用ChatGPT插件 首先在VSCode中打开扩展面板&#xff0c;搜索ChatGPT&#xff0c;安装蓝色圈出插件&#xff0c;如图所示&#xff1a; 安装完成后&#xff0c;需要重启VSCode 注册账号&#xff0c;如图所示&#xff1a; 然后在ChatGPT对话框中输入信息即可使用&#…