Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >C++位图

C++位图

原创
作者头像
梨_萍
发布于 2023-04-24 06:44:03
发布于 2023-04-24 06:44:03
4860
举报
文章被收录于专栏:梨+苹的C++梨+苹的C++

位图

代码语言:txt
AI代码解释
复制
给定40亿个不重复、没排序的无符号整数,再给一个无符号整数,如何快速判断一个数是否在这40亿个数中???

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

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

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

image-20230422112358980
image-20230422112358980

set

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

代码语言:c++
AI代码解释
复制
		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
位图set

Reset

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

代码语言:c++
AI代码解释
复制
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
位图reset

Test

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

代码语言:c++
AI代码解释
复制
		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
位图test1
位图test2
位图test2

整体代码

代码语言:c++
AI代码解释
复制
	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
image-20230423160349779

库里面也有

bitset

image-20230423160904693
image-20230423160904693

位图应用

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

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

image-20230423183904153
image-20230423183904153
代码语言:c++
AI代码解释
复制
//测试
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;
			}
		}
		}
代码语言:txt
AI代码解释
复制
一个文件有100亿个int,1G内存,设计算法找出次数不超过2次的所有整数

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

浅搓了个代码

代码语言:c++
AI代码解释
复制
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;

	};
代码语言:txt
AI代码解释
复制
给一个超过100G的log file,log中存着IP地址,设计算法找到出现次数最多的IP地址

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

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

image-20230423213026093
image-20230423213026093

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
云笔记横向评测:印象笔记、有道云笔记、为知笔记、OneNote、Notion、FlowUs、Wolai、飞书、语雀
某款软件是否好用,既需要根据其功能特性评估其优点和缺点,也需要分析用户的基本需求。以下是常见云笔记的深度评测。
数字花园
2022/06/26
16.8K0
云笔记横向评测:印象笔记、有道云笔记、为知笔记、OneNote、Notion、FlowUs、Wolai、飞书、语雀
免费、好用、强大的开源笔记软件综合评测
下面是一些比较著名的开源笔记软件。绝大多数开源软件都是针对某款知名笔记软件的替代品,比如印象笔记/EverNote、Roam Research、Notion 等笔记软件的替代品。
数字花园
2022/06/27
5.1K0
免费、好用、强大的开源笔记软件综合评测
全网最全的 Notion 类软件盘点
在前几天我发布了《Notion Like 软件横向评测》。今天继续在此基础上盘点 Notion Like 相关软件,以供参考。
数字花园
2022/05/31
1.4K0
全网最全的 Notion 类软件盘点
强大、好用的离线笔记软件综合评测:优点、缺点、对比
对于很多笔记用户而言,选择适合自己的笔记软件是一件难事。选择免费还是付费笔记应用?选择支持 Markdown 语法的笔记软件?要求离线或者云笔记?诸如此类,等等。
数字花园
2022/06/26
12.2K0
强大、好用的离线笔记软件综合评测:优点、缺点、对比
在线协作文档综合评测:Notion、FlowUs、Wolai、飞书、语雀、微软 Office、谷歌文档、金山文档、腾讯文档、石墨文档、Dropbox Paper
如今,在线协作文档已经成为效率办公的必备产品。然而,面临各种各样的在线文档产品,应该如何选择呢?
数字花园
2022/06/26
7.4K0
在线协作文档综合评测:Notion、FlowUs、Wolai、飞书、语雀、微软 Office、谷歌文档、金山文档、腾讯文档、石墨文档、Dropbox Paper
Logseq 评测:优点、缺点、评价、学习教程
Logseq 已有赶超 Roam Research 之势。从价格、功能等方面都具有相对优势。
数字花园
2022/07/03
2.3K0
Logseq 评测:优点、缺点、评价、学习教程
优质笔记软件评测(二)Logseq、Obsidian、思源笔记、FlowUs
一款本地优先的个人知识管理系统,融合块、大纲和双向链接,方便构建你永恒的数字花园。
数字花园
2022/07/02
4.8K0
优质笔记软件评测(二)Logseq、Obsidian、思源笔记、FlowUs
Notion Like 软件横向评测:Notion、FlowUs、Wolai
近几年,随着 Notion 的火爆,吸引了不少 Notion-Like 的产品。有的产品是将 Notion 的部分特性与自家的产品进行融合,比如语雀。有的是对标 Notion,比如 Wolai 和 FlowUs. 有的兼而有之,比如微软打算推出的 Loop, 虽然是将其融合至自家的 Office 产品系列,但是也能看到浓厚的 Notion 风格。此外,还有印象笔记的新产品 Verse.
数字花园
2022/05/31
2K0
Notion Like 软件横向评测:Notion、FlowUs、Wolai
关于 Notion-Like 工具的反思和畅想
在日常工作和学习过程中,我使用双链笔记比较多。然而,多数双链笔记的在线协作功能比较差,所以我又重新开始使用一年多前放弃的 Notion 类工具。
数字花园
2022/07/05
1.1K0
关于 Notion-Like 工具的反思和畅想
优秀笔记软件盘点:好看且强大的可视化笔记软件、知识图谱工具Heptabase、氢图、Walling、Reflect、InfraNodus、TiddlyWiki
想了解更多内容,可以近一步阅读我另外一篇文章 Heptabase:面向未来的知识操作系统
数字花园
2022/06/27
2.8K0
优秀笔记软件盘点:好看且强大的可视化笔记软件、知识图谱工具Heptabase、氢图、Walling、Reflect、InfraNodus、TiddlyWiki
免费、强大的开源笔记软件Joplin综合评测 —印象笔记的开源替代
在我的视野范围内,常见开源笔记软件包括Boostnote、GitNote、Joplin. 其中,前两者都是面向开发人员,全平台、支持中文、支持浏览器插件和扩展。而 Joplin 则面向一般用户。下面主要介绍 Joplin.
数字花园
2022/06/27
2.3K0
免费、强大的开源笔记软件Joplin综合评测 —印象笔记的开源替代
好用、强大的大纲编辑器综合评测:Workflowy、 Dynalist 、 幕布、 Cloud Outliner 、 坚果云大纲笔记、 双链笔记、 大纲模式软件
最近几年,大纲编辑器作为特殊的编辑器,逐渐被很多用户所知悉。其中,支持将大纲一键转换为思维导图的幕布可能最为有名。
数字花园
2022/06/27
3.9K0
好用、强大的大纲编辑器综合评测:Workflowy、 Dynalist 、 幕布、 Cloud Outliner 、 坚果云大纲笔记、 双链笔记、 大纲模式软件
协同办公笔记软件综合评测:飞书、语雀、Notion、FlowUs、Wolai
飞书文档汇集了文档、表格、思维笔记等在线创作工具,同时为文件提供安全、强大的云端存储和内容管理能力,文档所有者可以根据需要灵活设置浏览、编辑、评论、分享等权限,让协作有序又高效。
数字花园
2022/06/26
8.6K0
协同办公笔记软件综合评测:飞书、语雀、Notion、FlowUs、Wolai
Notion 类笔记软件如何选择?Notion 、FlowUs 、Wolai 对比评测
Notion 是什么?这是一款主张 All in One、基于各种 Block 组合的块编辑器。此外,Notion 借鉴了 Airtable 的 Database 功能,提出 Open as Page, 进化成了基于各种 Page 页面为基础的、独具特色 Database.
数字花园
2022/07/05
4.3K0
Notion 类笔记软件如何选择?Notion 、FlowUs 、Wolai 对比评测
免费、强大、高颜值的笔记软件评测: OneNote、Heptabase、氢图、FlowUs
OneNote 的强大与自由,很大程度上便是由类似白板的画布体验所赋予的。那么,推荐你试用 Heptabase.
数字花园
2022/06/28
2.3K0
免费、强大、高颜值的笔记软件评测: OneNote、Heptabase、氢图、FlowUs
在线协作产品哪家强?微软 Loop 、Notion、FlowUs
微软 Loop 发布。这款借鉴 Loop 的新产品,与以往的 Notion、FlowUs等产品有什么区别呢?
数字花园
2022/07/05
1.3K0
在线协作产品哪家强?微软 Loop 、Notion、FlowUs
如何选择适合你的笔记软件?印象笔记 、Notion、FlowUs
对于很多效率人士或者笔记软件用户而言,基本都知道大名鼎鼎的印象笔记。其中,多数人或多或少用过印象笔记。多数重度笔记用户,都曾经是或者依然是印象笔记的忠实用户。
数字花园
2022/06/26
2.1K0
如何选择适合你的笔记软件?印象笔记 、Notion、FlowUs
大纲笔记软件 Workflowy 综合评测:优点、缺点和评价
尽管 Workflowy 后面的不少大纲编辑器。比如,Dynalist 允许将任何节点切换为待办列表、支持 LaTeX 、支持文章模式等新的特性。Workflowy 还是以其纯粹轻便、简约不简单等功能吸引了不少用户。Workflowy 的界面设计十分优雅,编辑器流畅,新增加的看板模式极大提高了组织信息的能力。
数字花园
2022/06/27
1.8K0
大纲笔记软件 Workflowy 综合评测:优点、缺点和评价
好看、好用、强大的手写笔记软件综合评测:Notability、GoodNotes、MarginNote、随手写、Notes Writers、FlowUs
与普通的笔记编辑器相比,手写笔记软件相对少一些。其中,比较出名的并不多。下面介绍一些比较主流、备受好评的,兼具有好看、好用、强大等特点的手写笔记软件。其中,首先介绍传统被忽略的两款笔记软件 OneNote 和 苹果备忘录。随后测评了包括 Notability、GoodNotes、MarginNote、随手写、Notes Writers、CollaNote、CollaNote、Prodrafts、Noteshelf、FlowUs.
数字花园
2022/07/03
11.1K0
好看、好用、强大的手写笔记软件综合评测:Notability、GoodNotes、MarginNote、随手写、Notes Writers、FlowUs
双链笔记·思源笔记综合评测:优点、缺点、评价
一款本地优先的个人知识管理系统,融合块、大纲和双向链接,方便构建你永恒的数字花园。
数字花园
2022/07/03
3.3K0
双链笔记·思源笔记综合评测:优点、缺点、评价
推荐阅读
云笔记横向评测:印象笔记、有道云笔记、为知笔记、OneNote、Notion、FlowUs、Wolai、飞书、语雀
16.8K0
免费、好用、强大的开源笔记软件综合评测
5.1K0
全网最全的 Notion 类软件盘点
1.4K0
强大、好用的离线笔记软件综合评测:优点、缺点、对比
12.2K0
在线协作文档综合评测:Notion、FlowUs、Wolai、飞书、语雀、微软 Office、谷歌文档、金山文档、腾讯文档、石墨文档、Dropbox Paper
7.4K0
Logseq 评测:优点、缺点、评价、学习教程
2.3K0
优质笔记软件评测(二)Logseq、Obsidian、思源笔记、FlowUs
4.8K0
Notion Like 软件横向评测:Notion、FlowUs、Wolai
2K0
关于 Notion-Like 工具的反思和畅想
1.1K0
优秀笔记软件盘点:好看且强大的可视化笔记软件、知识图谱工具Heptabase、氢图、Walling、Reflect、InfraNodus、TiddlyWiki
2.8K0
免费、强大的开源笔记软件Joplin综合评测 —印象笔记的开源替代
2.3K0
好用、强大的大纲编辑器综合评测:Workflowy、 Dynalist 、 幕布、 Cloud Outliner 、 坚果云大纲笔记、 双链笔记、 大纲模式软件
3.9K0
协同办公笔记软件综合评测:飞书、语雀、Notion、FlowUs、Wolai
8.6K0
Notion 类笔记软件如何选择?Notion 、FlowUs 、Wolai 对比评测
4.3K0
免费、强大、高颜值的笔记软件评测: OneNote、Heptabase、氢图、FlowUs
2.3K0
在线协作产品哪家强?微软 Loop 、Notion、FlowUs
1.3K0
如何选择适合你的笔记软件?印象笔记 、Notion、FlowUs
2.1K0
大纲笔记软件 Workflowy 综合评测:优点、缺点和评价
1.8K0
好看、好用、强大的手写笔记软件综合评测:Notability、GoodNotes、MarginNote、随手写、Notes Writers、FlowUs
11.1K0
双链笔记·思源笔记综合评测:优点、缺点、评价
3.3K0
相关推荐
云笔记横向评测:印象笔记、有道云笔记、为知笔记、OneNote、Notion、FlowUs、Wolai、飞书、语雀
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档