位图(bitset)的使用【STL】

news2024/11/26 4:22:02

文章目录

  • 1. 介绍
    • 1.1 背景
    • 1.2 概念
      • 1.3 应用
  • 2. 位图的使用
    • 2.1 原型
    • 2.2 构造位图
    • 2.3 常用接口
    • 2.4 示例
    • 2.4 常用运算符
      • 2.4.1 >>和<<
      • 2.4.2 赋值运算符、关系运算符、复合赋值运算符、单目运算符
      • 2.4.3 位运算符
      • 2.4.4 [ ]运算符

1. 介绍

1.1 背景

一道面试题:

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

在目前为止,我们能想到的最快的办法有两种:

  1. 排序+二分查找;
  2. 用搜索树如红黑树、哈希表等查找效率非常高的数据结构查找。

虽然从时间复杂度上看,它们的效率还可以,一个是 O ( l o g 2 N ) O(log_2N) O(log2N),一个是 l o g ( N ) log(N) log(N),但是这个问题从一开始就和一般的查找问题不同:

“40亿个不重复的无符号整数”,在计算机眼中,一个unsigned整数是4个字节(32位机器),那么40亿个就是40亿*4字节,大约是15GB。这么大的数据量,使用哈希表和搜索树都不大可能有效,因为它们作为一种数据结构本身就占有一定的内存空间,例如结点类的大小。每个结点除了数据本身还有其他结构附带的内存空间占用,哈希表能达到45G左右,搜索树更是达到了接近60G。而一般的机器内存并没有这么大,排除第二种方案。

排序+二分查找也不行,还是因为数据量太大,只能作为磁盘文件处理,但是二分查找和外排序都很慢,造成它们速度慢的主要原因是磁盘查找扇区的速度很慢。

即使是强如SSD这样的能够高速读写的固态硬盘,它的读写速度和内存依然相形见绌,所以它的“高速”是相对于传统机械硬盘而言的。

位图就是解决诸如“大海捞针”这样的海量数据问题的。

1.2 概念

位图(bitmap),将每一个bit位的0和1作为集合中某个元素的状态:

  • 0:不存在
  • 1:存在

常用语海量数据处理和数据查重,是一种较高空间利用率的数据结构。

漫画:Bitmap算法

1.3 应用

  1. 快速查找某个数据是否在一个集合中;
  2. 排序;
  3. 求两个集合的交集、并集等;
  4. 操作系统中磁盘块标记;
  5. 内核中信号标志位(信号屏蔽字和未决信号集)。
    在这里插入图片描述

上图中的比特位序号从右到左递增,说明机器是小端机,大多数机器都是小端机。

友情链接:大小端模式

在32位机器中,每个unsigned整数都是4个字节,那么对于上面这个例子,40亿个unsigned整数对应40亿个比特位,一个整数有32个比特位,那么40亿个数也就占512MB。内存消耗极大减少。

2. 位图的使用

STL标准库内置了位图,它叫做bitset。

2.1 原型

template <size_t N> class bitset;
  • N:bitset 的大小,以位数表示。

它被包含在头文件<bitset>中。

2.2 构造位图

主要有三种构造位图的方法:

  1. 构造一个16位的位图,默认每位都是0:

    bitset<16> bs1; // 0000000000000000
    
  2. 用一个具体的数值的二进制序列构造位图:

    bitset<16> bs2(0xffffffff); // 1111111111111111
    
  3. (必须)用一个由0和1组成的字符串构造位图:

    bitset<16> bs3(string("1010101001")); // 0000001010101001
    

2.3 常用接口

成员函数功能
set设置指定位或所有位
reset清空指定位或所有位
flip反转指定位或所有位
test获取指定位的状态
count获取被设置位的个数
size获取可以容纳的位的个数
any如果有任何一个位被设置则返回true
none如果没有位被设置则返回true
all如果所有位都被设置则返回true

2.4 示例

void test1()
{
	bitset<8> bs;
	cout << "bitset<8> bs:" << bs << endl;

	bs.set();			// 设置所有位
	cout << "bs.set():    " << bs << endl;

	bs.flip();			// 反转所有位
	cout << "bs.flip():   " << bs << endl;

	bs.set(1);			// 设置第1位
	cout << "bs.set(1):   " << bs << endl;

	bs.reset(1);		// 清空第1位
	cout << "bs.reset(1): " << bs << endl;

	bs.flip(1);			// 反转第1位
	cout << "bs.flip(1):  " << bs << endl;

	int size = bs.size();// 可表示位的个数
	cout << "bs.size():   " << size << endl;

	bool any = bs.any(); // 任何一个位被设置返回true
	cout << "any be setted:" << any << endl;

	bs.reset();			 // 清空所有位
	bool none = bs.none();// 没有位被设置返回true
	cout << "none be setted:" << none << endl;
}

输出

bitset<8> bs:00000000
bs.set():    11111111
bs.flip():   00000000
bs.set(1):   00000010
bs.reset(1): 00000000
bs.flip(1):  00000010
bs.size():   8
any be setted:1
none be setted:1

2.4 常用运算符

2.4.1 >>和<<

bitset容器重载了>>和<<运算符(流插入和流输出),所以可以直接对容器实例化出的对象进行输入输出操作:

void test2()
{
	bitset<8> bs;
	cin >> bs;
	cout << bs << endl;
}

输入:

1010

输出:

00001010

2.4.2 赋值运算符、关系运算符、复合赋值运算符、单目运算符

  • 赋值运算符:=;
  • 关系运算符:==、!=;
  • 复合赋值运算符:&=、|=、^=、<<=、>>=;
  • 单目运算符:~。
void test3()
{
	bitset<8> bs1(string("11100000"));
	bitset<8> bs2(string("00000111"));

	bool eql = bs1 != bs2;
	cout << "bs1!=bs2:  " << eql << endl;

	bs1 >>= 3;
	cout << "bs1>>3:    " << bs1 << endl;

	bs2 ^= bs1;
	cout << "bs2 ^= bs1:" << bs2 << endl;
}

输出:

bs1!=bs2:  1
bs1>>3:    00011100
bs2 ^= bs1:00011011

2.4.3 位运算符

位图也可以直接用三个位运算符对位操作:

void test4()
{
	bitset<8> bs1(string("10101010"));
	bitset<8> bs2(string("01010101"));

	cout << (bs1 & bs2) << endl;
	cout << (bs1 | bs2) << endl;
	cout << (bs1 ^ bs2) << endl;
}

输出:

00000000
11111111
11111111

2.4.4 [ ]运算符

位操作作为计算机中最精细的操作,速度理应是非常快的,所以可以认为是像数组一样随机访问不同序号的比特位:

void test5()
{
	bitset<8> bs(string("10101010"));
	cout << bs[1] << endl;
	bs[7] = 0;
	cout << bs << endl;
}

输出:

1
00101010

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

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

相关文章

读懂ShuffleNet V2

ShuffleNetV2介绍 https://arxiv.org/abs/1807.11164 深度卷积神经网络的架构创新显著的提升了在ImageNet数据集上的分类准确率&#xff0c;如VGG、GoogleNet、ResNet、DenseNet、ResNeXt、SE-Net以及自动网络架构搜索获得的方案。然而除了准确率&#xff0c;计算复杂度是另一…

实操分享:台式数字万用表测电压,手动测试VS万用表软件NS-Multimeter

台式数字万用表可以测量电流、电压、电阻、温度等多种参数&#xff0c;是电子工程师必备的仪器之一。本篇文章纳米软件Namisof小编将为大家分享&#xff1a;使用台式数字万用表手动测电压和万用表软件测电压的方法。本次将用DMM6500台式数字万用表为大家进行演示说明。 一、DMM…

大学生图书馆网页设计模板代码 DIV布局书店网页作业成品 学校书籍网页制作模板 学生简单书籍阅读网站设计成品

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

ESP-C3入门1. VSCode+IDF 开发环境

ESP-C3入门1. VSCodeIDF 开发环境一、芯片说明1. 主要参数2. 内部结构图ESP32-C3-MINI-1内部架构图&#xff1a;ESP32-C3-MINI-1U内部架构图&#xff1a;3. 引脚4. 引脚描述5. strapping管脚6. 系统复位二、idf-vscode开发环境搭建1. 安装vscode2. idf配置&#xff08;1&#x…

【AI with ML】第 5 章 :自然语言处理简介

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

【Spring】——13、BeanPostProcessor在Spring底层是如何使用的?

&#x1f4eb;作者简介&#xff1a;zhz小白 公众号&#xff1a;小白的Java进阶之路 专业技能&#xff1a; 1、Java基础&#xff0c;并精通多线程的开发&#xff0c;熟悉JVM原理 2、熟悉Java基础&#xff0c;并精通多线程的开发&#xff0c;熟悉JVM原理&#xff0c;具备⼀定的线…

本周推荐 | 表达式引擎的组合子实现方案

推荐语&#xff1a;本文清晰而详细地介绍了如何使用 Parser 组合子方案&#xff0c;结合 Monad 通过合理的分层、抽象和组合&#xff0c;在性能达标的情况下实现消息场景中函数式的表达式解析。非常具有实践意义&#xff0c;推荐阅读学习&#xff01;——大淘宝技术终端开发工程…

java+mysql基于ssm的网上订餐外卖管理系统

随着人们生活节奏的加快,网上订餐和外卖是当前很多人的一个选择,如何能够让更多的人吃上美味健康的饭菜是本系统研究的一个重要内容,同时本系统还拥有外卖的功能,让食客可以第一时间享受的想要吃到的美食 根据条件需要,系统结构主要由三大用户组成。一是买家组成的买家用户,二…

虹科技术 | 终端入侵防御 | 在重大攻击中发现新的Babuk勒索软件

11月期间&#xff0c;Morphisec在调查一个客户的防范事件时发现了Babuk勒索软件的一个全新变种。Babuk在2021年初首次被发现&#xff0c;当时它开始针对企业进行双重勒索攻击&#xff0c;以窃取和加密数据。这一年晚些时候&#xff0c;一个威胁者在一个讲俄语的黑客论坛上泄露了…

【案例教程】气象数据相关分析:如何使用格点数据分析中国霜冻灾害变化技术

【查看原文】气象数据相关分析及使用系列&#xff1a;如何使用格点数据分析中国霜冻灾害变化技术 霜冻是一种短历时的农业气象灾害&#xff0c;它是由于日最低气温下降&#xff0c;使植物茎、叶处温度下降到0℃以下&#xff0c;导致正在生长的植物受到冻伤的现象。霜冻出现的早…

深度学习——数据增广(笔记)+代码

1.为什么要进行数据增广&#xff1f; ①大型数据集是深度网络的前提条件 ②图像增广对训练数据进行一系列的随机变化&#xff0c;生成相似但不同的训练样本&#xff0c;从而扩大训练集的规模 ③数据增广&#xff1a;可以处理图片和文本和语音。 ④对于图片的处理方式包括&a…

FITC-PEG-DBCO,Fluorescein-PEG-DBCO,荧光素-PEG-DBCO

【产品描述】 DBCO试剂在水性缓冲液中具有快速动力学和稳定性&#xff0c;可用于标记叠氮化物修饰的生物分子&#xff0c;具有高特异性和反应性。FITC具有高吸收率的荧光量子产率和良好的水溶性等特点&#xff0c;是生物学中应用广泛的一种绿色荧光素衍生物&#xff0c;除了用作…

【TypeScript系列】【一篇就够】TypeScript知识点总结(一)

00 TypeScript简介 TypeScript是JavaScript的超集。它对JS进行了扩展&#xff0c;向JS中引入了类型的概念&#xff0c;并添加了许多新的特性。TS代码需要通过编译器编译为JS&#xff0c;然后再交由JS解析器执行。TS完全兼容JS&#xff0c;换言之&#xff0c;任何的JS代码都可以…

神经网络科研绘图可视化工具

本文介绍10种科研绘图可视化工具。 目录1.神经网络框架自带的可视化工具库2.NN-SVG3.PlotNeuralNet4.netron5.ZETANE6.Tensorspace.js7.GRAPHCORE8.nn_vis9.PowerPoint1.神经网络框架自带的可视化工具库 pytorch&#xff1a;pytorchviz库&#xff1b; keras&#xff1a;keras.…

Map和Set

目录 1.搜索 1.1 概念 1.2 模型 2.Map的使用 2.1 Map说明 2.2 Map.Entry说明,v> 2.3 Map的常见方法 2.3.1 V put(K key, V value) 2.3.2 V get(Object key) 2.3.3 V getOrDefault(Object key, V defaultValue) 2.3.4 Set keySet() Collection values() 2.3.5 S…

JavaWeb语法二:Thread类的基本使用

目录 1.创建线程 1.2&#xff1a;run()和start()方法 1.3&#xff1a;Thread的几个常见属性 2.线程的有关操作 2.1&#xff1a;启动一个线程&#xff1a;start() 2.2&#xff1a;中断一个线程 2.2.1&#xff1a;使用自定义的变量来作为标志位 2.2.2&#xff1a;使用Thr…

高校校园网络

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a;开发工具IDEA-2020.1,数据库mysql55.527,SSM框架&#xff0c;jdk版本"1.8.0_74"&#xff0c;java语言。 管理员…

小白年薪26万,为什么Python岗位的薪资越来越高?问题解析

人工智能和大数据概念的兴起&#xff0c;带动了Python的快速增长——Python语言逻辑简洁、入门简单、生态丰富&#xff0c;几乎成为几个新兴领域的不二选择。而除了这两个领域&#xff0c;Python还有更多的适用领域&#xff1a;爬虫、web、自动化运维等领域都非常适合Python发挥…

大二学生HTML期末作业、个人主页网页制作作业

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

代码随想录第八天

专题&#xff1a;字符串 题目&#xff1a; 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。不要给另外的数组分配额外的空间&#xff0c;你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。你可以假设数组中的所…