前往小程序,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 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Transformers 4.37 中文文档(五十九)
SwitchTransformers 模型是由 William Fedus、Barret Zoph 和 Noam Shazeer 在Switch Transformers: Scaling to Trillion Parameter Models with Simple and Efficient Sparsity中提出的。
ApacheCN_飞龙
2024/06/26
6750
Transformers 4.37 中文文档(五十)
OPT 模型是由 Meta AI 在Open Pre-trained Transformer Language Models中提出的。OPT 是一系列开源的大型因果语言模型,性能与 GPT3 相似。
ApacheCN_飞龙
2024/06/26
4320
Transformers 4.37 中文文档(五十)
Transformers 4.37 中文文档(五十六)
RoBERTa-PreLayerNorm 模型由 Myle Ott, Sergey Edunov, Alexei Baevski, Angela Fan, Sam Gross, Nathan Ng, David Grangier, Michael Auli 在 fairseq: A Fast, Extensible Toolkit for Sequence Modeling 中提出。它与在 fairseq 中使用 --encoder-normalize-before 标志相同。
ApacheCN_飞龙
2024/06/26
1700
Transformers 4.37 中文文档(二十一)
Bart 模型是由 Mike Lewis, Yinhan Liu, Naman Goyal, Marjan Ghazvininejad, Abdelrahman Mohamed, Omer Levy, Ves Stoyanov 和 Luke Zettlemoyer 在 2019 年 10 月 29 日提出的,题为 BART: Denoising Sequence-to-Sequence Pre-training for Natural Language Generation, Translation, and Comprehension。
ApacheCN_飞龙
2024/06/26
2110
Transformers 4.37 中文文档(二十五)
请注意,BlenderbotSmallModel 和 BlenderbotSmallForConditionalGeneration 仅与检查点facebook/blenderbot-90M结合使用。较大的 Blenderbot 检查点应该与 BlenderbotModel 和 BlenderbotForConditionalGeneration 一起使用
ApacheCN_飞龙
2024/06/26
1990
Transformers 4.37 中文文档(二十四)
BigBird 模型是由 Zaheer, Manzil 和 Guruganesh, Guru 以及 Dubey, Kumar Avinava 和 Ainslie, Joshua 和 Alberti, Chris 和 Ontanon, Santiago 和 Pham, Philip 和 Ravula, Anirudh 和 Wang, Qifan 和 Yang, Li 等人在Big Bird: Transformers for Longer Sequences中提出的。BigBird 是一种基于稀疏注意力的 Transformer,它将 Transformer 模型(如 BERT)扩展到更长的序列。除了稀疏注意力,BigBird 还将全局注意力以及随机注意力应用于输入序列。从理论上讲,已经证明应用稀疏、全局和随机注意力可以逼近全注意力,同时对于更长的序列来说在计算上更加高效。由于具有处理更长上下文的能力,BigBird 在各种长文档 NLP 任务上表现出比 BERT 或 RoBERTa 更好的性能,如问答和摘要。
ApacheCN_飞龙
2024/06/26
1530
Transformers 4.37 中文文档(三十七)
OpenAI GPT-2 模型是由 Alec Radford、Jeffrey Wu、Rewon Child、David Luan、Dario Amodei 和 Ilya Sutskever 在 OpenAI 提出的,它是一个因果(单向)变压器,使用语言建模在一个大约 40GB 的文本数据语料库上进行预训练。
ApacheCN_飞龙
2024/06/26
1370
Transformers 4.37 中文文档(五十五)
如果您在运行此模型时遇到任何问题,请重新安装支持此模型的最后一个版本:v4.30.0。您可以通过运行以下命令来执行:pip install -U transformers==4.30.0。
ApacheCN_飞龙
2024/06/26
3110
Transformers 4.37 中文文档(八十一)
Whisper 模型由 Alec Radford、Jong Wook Kim、Tao Xu、Greg Brockman、Christine McLeavey、Ilya Sutskever 在通过大规模弱监督实现稳健语音识别中提出。
ApacheCN_飞龙
2024/06/26
1.1K0
Transformers 4.37 中文文档(三十六)
我们介绍了 GPT-NeoX-20B,这是一个拥有 200 亿参数的自回归语言模型,经过 Pile 训练,其权重将通过宽松许可证免费向公众开放。据我们所知,这是在提交时具有公开可用权重的最大稠密自回归模型。在这项工作中,我们描述了 GPT-NeoX-20B 的架构和训练,并评估了其在一系列语言理解、数学和基于知识的任务上的性能。我们发现,GPT-NeoX-20B 是一个特别强大的少样本推理器,在进行五次评估时性能提升明显,而与大小相似的 GPT-3 和 FairSeq 模型相比。我们开源了训练和评估代码,以及模型权重,链接为 github.com/EleutherAI/gpt-neox。
ApacheCN_飞龙
2024/06/26
4290
Transformers 4.37 中文文档(三十六)
Transformers 4.37 中文文档(六十二)
**免责声明:**如果您看到异常情况,请提交GitHub 问题并指定@patrickvonplaten
ApacheCN_飞龙
2024/06/26
2850
Transformers 4.37 中文文档(二十二)
BARThez 模型是由 Moussa Kamal Eddine、Antoine J.-P. Tixier 和 Michalis Vazirgiannis 于 2020 年 10 月 23 日提出的BARThez: a Skilled Pretrained French Sequence-to-Sequence Model。
ApacheCN_飞龙
2024/06/26
2800
Transformers 4.37 中文文档(二十九)
DeBERTa 模型是由 Pengcheng He、Xiaodong Liu、Jianfeng Gao、Weizhu Chen 在DeBERTa: Decoding-enhanced BERT with Disentangled Attention中提出的,它基于 2018 年发布的 Google 的 BERT 模型和 2019 年发布的 Facebook 的 RoBERTa 模型。
ApacheCN_飞龙
2024/06/26
4810
Transformers 4.37 中文文档(五十七)
RoCBert 模型是由 HuiSu、WeiweiShi、XiaoyuShen、XiaoZhou、TuoJi、JiaruiFang、JieZhou 在 RoCBert: Robust Chinese Bert with Multimodal Contrastive Pretraining 中提出的。它是一个经过预训练的中文语言模型,在各种形式的对抗攻击下具有鲁棒性。
ApacheCN_飞龙
2024/06/26
2840
Transformers 4.37 中文文档(二十)
特征提取器负责为音频或视觉模型准备输入特征。这包括从序列中提取特征,例如,对音频文件进行预处理以生成 Log-Mel Spectrogram 特征,从图像中提取特征,例如,裁剪图像文件,但也包括填充、归一化和转换为 NumPy、PyTorch 和 TensorFlow 张量。
ApacheCN_飞龙
2024/06/26
4750
Transformers 4.37 中文文档(三十一)
EncoderDecoderModel 可以用于初始化一个序列到序列模型,其中预训练的自编码模型作为编码器,预训练的自回归模型作为解码器。
ApacheCN_飞龙
2024/06/26
3040
Transformers 4.37 中文文档(四十二)
M2M100 模型是由 Angela Fan、Shruti Bhosale、Holger Schwenk、Zhiyi Ma、Ahmed El-Kishky、Siddharth Goyal、Mandeep Baines、Onur Celebi、Guillaume Wenzek、Vishrav Chaudhary、Naman Goyal、Tom Birch、Vitaliy Liptchinsky、Sergey Edunov、Edouard Grave、Michael Auli、Armand Joulin 在 Beyond English-Centric Multilingual Machine Translation 中提出的。
ApacheCN_飞龙
2024/06/26
3700
Transformers 4.37 中文文档(四十二)
Transformers 4.37 中文文档(九十六)
VipLlava 模型是由 Mu Cai、Haotian Liu、Siva Karthik Mustikovela、Gregory P. Meyer、Yuning Chai、Dennis Park、Yong Jae Lee 在《Making Large Multimodal Models Understand Arbitrary Visual Prompts》中提出的。
ApacheCN_飞龙
2024/06/26
4940
Transformers 4.37 中文文档(九十四)
SpeechEncoderDecoderModel 可用于使用任何预训练语音自编码模型作为编码器(例如 Wav2Vec2,Hubert)和任何预训练自回归模型作为解码器初始化语音到文本模型。
ApacheCN_飞龙
2024/06/26
3140
Transformers 4.37 中文文档(九十四)
Transformers 4.37 中文文档(四十一)
LongT5 模型是由 Mandy Guo、Joshua Ainslie、David Uthus、Santiago Ontanon、Jianmo Ni、Yun-Hsuan Sung 和 Yinfei Yang 在LongT5: Efficient Text-To-Text Transformer for Long Sequences中提出的。它是在文本到文本去噪生成设置中预训练的编码器-解码器变压器。LongT5 模型是 T5 模型的扩展,它可以使用两种不同的高效注意力机制之一——(1)局部注意力,或(2)瞬时全局注意力。
ApacheCN_飞龙
2024/06/26
1880
推荐阅读
相关推荐
Transformers 4.37 中文文档(五十九)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档