C++bitset类型

news2024/11/24 20:33:35

bitset类型

我们介绍了将整型运算对象当作二进制位集合处理的一些内置运算符。

  1. 标准库还定义了bitset类,使得位运算的使用更为容易,并且能够处理超过最长整型类型大小的位集合。
  2. bitset类定义在头文件bitset中。


定义和初始化bitset

bitset类是一个类模板,它类似array类,具有固定的大小。当我们定义一个bitset时,需要声明它包含多少个二进制位:

bitset<32>bitvec(10);// 32位;低位为 1,其他位为 0

大小必须是一个常量表达式。

这条语句定义bitvec为一个包含32位的bitset。就像 vector 包含未命名的元素一样,bitset中的二进制位也是未命名的,我们通过位置来访问它们。

二进制位的位置是从0开始编号的。

因此,bitvec包含编号从0到31的32个二进制位。编号从0开始的二进制位被称为低位,编号到31结束的二进制位被称为高位。

初始化bitset的方法
bitset<n>b;b有n位;每一位均为0。此构造函数是一个constexpr
bitset<n> b(u);b是unsigned lonq long值u的低n位的拷贝。如果n大于 unsigned long lonq的大小,则b中超出unsigned long long 的高位被置为 0。此构造函数是一个 constexpr
bitset<n> b(s, pos,zero,one);

 b是string s从位置pos开始m个字符的拷贝。

s只能包含zero和one; 字符如果s包含任何其他字符,构造函数会抛出invalid_argument 异常。

字符在b中分别保存为 zero和one。

pos 默认为 0,m 默认为 string::npos, zero 默认为'0',one默认为'1’

bitset<n> b(cP, pos,m, zero, one);

与上一个构造函数相同,但从cp指向的字符数组中拷贝字符。

  • 如果未提供m,则cp必须指向一个C风格字符串。
  • 如果提供了m,则从cp开始必须至少有m个zero或one字符

接受一个string或一个字符指针的构造函数是explicit的。在新标准中增加了为0和1指定其他字符的功能。

用 unsigned 值初始化 bitset

当我们使用一个整型值来初始化bitset时,此值将被转换为 unsigned long long类型并被当作位模式来处理。

bitset中的二进制位将是此模式的一个副本。

  • 如果bitset的大小大于一个unsigned long long中的二进制位数,则剩余的高位被置为0。
  • 如果bitset的大小小于一个unsigned long long中的二进制位数,则只使用给定值中的低位,超出bitset大小的高位被丢弃:
#include<iostream>
#include<bitset>

using namespace std;	
int main()
{

// bitvec1比初始值小;初始值中的高位被丢弃
	bitset<13> bitvec1(0xbeef);// 二进制位序列为 1111011101111
	cout <<"bitvec1:"<< bitvec1 << endl;
	//bitvec2比初始值大;它的高位被置为0
	bitset<20> bitvec2(0xbeef);//二进制位序列为00001011111011101111
	cout << "bitvec2:" << bitvec2 << endl;
	// 在64位机器中,long long OULL是64个0比特,因此~0ULL是64个1
	bitset<128> bitvec3(~0ULL);//0~63位为1;63~127位为0
	cout << "bitvec3:" << bitvec3 << endl;
}

从一个string 初始化bitset


我们可以从一个string或一个字符数组指针来初始化bitset。

两种情况下,字符都直接表示位模式。

与往常一样,当我们使用字符串表示数时,字符串中下标最小的字符对应高位,反之亦然:

bitset<32> bitvec4("1100”);// 2、3两位为1,剩余两位为0

如果string包含的字符数比bitset少,则bitset的高位被置为0。


string的下标编号习惯与bitset恰好相反:string中下标最大的字符(最右字符)用来初始化bitset中的低位(下标为0的二进制位)。

当你用一个string初始化一个bitset时,要记住这个差别。
 

我们不必使用整个string来作为bitset的初始值,可以只用一个子串作为初始值:

string str("1111111000000011001101");
bitset<32> bitvec5(str, 5, 4);//从str[5]开始的四个二进制位,1100
cout << bitvec5 << endl;
bitset<32> bitvec6(str, str.size() - 4); //使用最后四个字符
cout << bitvec6 << endl;

  • 此处,bitvec5用str中从str[5]开始的长度为4的子串进行初始化。与往常一样,子串的最右字符表示最低位。因此,bitvec5中第3位到第0位被设置为1100,剩余位被设置为0。
  • 传递给bitvec6的初始值是一个string和一个开始位置,因此bitvec6用str中倒数第四个字符开始的子串进行初始化。bitvec6中剩余二进制位被初始化为0。

下图说明了这两个初始化过程

bitset 操作

bitset类定义了多种检测或设置一个或多个二进制位的方法。

bitset类还支持我们介绍过的位运算符,这些运算符用于bitset对象的含义与内置运算符用于unsigned运算对象相同。

bitset操作
b.any()b 中是否存在置位的二进制位
b.all()b 中所有位都置位了吗
b.none()b 中不存在置位的二进制位吗
b.count()b中置位的位数
b.size()一个constexpr函数,返回b中的位数
b.test(pos)若pos位置的位是置位的,则返回true,否则返回false

b.set (pos,v)

b.set()

将位置 pos 处的位设置为bool 值v,v默认为true。

如果未传递实参,则将b中所有位置位

b.reset (pos)

b.reset()

将位置 pos处的位复位或将b中所有位复位
b.flip(pos)
b.flip()
改变位置 pos 处的位的状态或改变b中每一位的状态
b[pos]访问b中位置pos处的位;如果b是const的,则当该位置位时b[pos]返回一个boo1值true,否则返回false

b.to_ulong()

b.to_ullong()

返回一个unsigned long或一个unsigned long long值,其位模式与b相同。

如果b中位模式不能放入指定的结果类型,则抛出一个overflow_error异常

b.to_string(zero,
one)

返回一个string,表示b中的位模式。

zero和one的默认值分别为0和1,用来表示b中的0和1

os << b将b中二进制位打印为字符1或0,打印到流os
is >> b从is读取字符存入b。当下一个字符不是1或0时,或是已经读入b.size()个位时,读取过程停止

count、size、all、any 和none 等几个操作都不接受参数,返回整个bitset的状态。

其他操作——set、reset和flip则改变bitset的状态。改变bitset状态的成员函数都是重载的。

对每个函数,不接受参数的版本对整个集合执行给定的操作;接受一个位置参数的版本则对指定位执行操作:

cout << boolalpha;
bitset<32> bitvec(1U); // 32位;低位为1,剩余位为0
bool is_set = bitvec.any(); // true,因为有1位置位
cout << is_set << endl;

bool is_not_set = bitvec.none(); // false,因为有1位置位了
cout << is_not_set << endl;

bool all_set = bitvec.all(); // false,因为只有1位置位
cout << all_set << endl;

size_t onBits = bitvec.count(); // 返回1
cout << onBits << endl;

size_t sz = bitvec.size(); // 返回32
cout << sz << endl;

bitvec.flip(); // 翻转bitvec中的所有位
cout << bitvec << endl;

bitvec.reset();// 将所有位复位
cout << bitvec << endl;

bitvec.set(); // 将所有位置位
cout << bitvec << endl;

cout << noboolalpha;

 

当bitset对象的一个或多个位置位(即,等于1)时,操作any返回true。

相反,当所有位复位时,none返回true。新标准引入了all操作,当所有位置位时返回true。

操作count和size返回 size_t类型的值,分别表示对象中置位的位数或总位数。

函数size是一个constexpr函数,因此可以用在要求常量表达式的地方。

成员flip、set、 reset及test允许我们读写指定位置的位:

string str("111111000000");
bitset<12> bitvec(str);
cout << bitvec << endl;
bitvec.flip(0); // 翻转第一位
cout << bitvec << endl;

bitvec.set(bitvec.size() - 1);//置位最后一位
cout << bitvec << endl;

bitvec.set(0, 0); //复位第一位
cout << bitvec << endl;

bitvec.reset(1); //复位第1位
cout << bitvec << endl;

bitvec.test(0); //返回false,因为第一位是复位的
cout << bitvec << endl;

 

下标运算符对const属性进行了重载。

const版本的下标运算符在指定位置位时返回true,否则返回 false。

非 const版本返回bitset定义的一个特殊类型,它允许我们操纵指定位的值:

string str("111111000000");
	bitset<12> bitvec(str);
	cout << bitvec << endl;
	
	bitvec[0] = 1; // 将第一位复位
	cout << bitvec << endl;

	bitvec[11] = bitvec[0]; // 将最后一位设置为与第一位一样
	cout << bitvec << endl;

	bitvec[0].flip(); // 翻转第一位
	cout << bitvec << endl;

	~bitvec[0]; //等价操作,也是翻转第一位
	cout << bitvec << endl;

	bool b = bitvec[0]; //将bitvec[0]的值转换为bool类型
	cout << bitvec << endl;

 

提取 bitset的值

to_ulong和to _ullong操作都返回一个值,保存了与bitset对象相同的位模式。

只有当bitset的大小小于等于对应的大小(to_ulong为unsigned long, to_ullong为unsigned long long)时,我们才能使用这两个操作:

string str("111111000000");
bitset<12> bitvec(str);
bool b = bitvec[0]; //将bitvec[0]的值转换为bool类型
cout << bitvec << endl;

 


如果 bitset 中的值不能放入给定类型中,则这两个操作会抛出一个overflow_error异常。

bitset 的IO运算符

输入运算符从一个输入流读取字符,保存到一个临时的string对象中。

直到读取的字符数达到对应bitset的大小时,或是遇到不是1或0的字符时,或是遇到文件尾或输入错误时,读取过程才停止。

随即用临时string对象来初始化bitset。

如果读取的字符数小于bitset的大小,则与往常一样,高位将被置为0。

输出运算符打印一个bitset对象中的位模式:

bitset<16> bits;
cin >>bits; //从cin读取最多16个0或1
cout << "bits:" << bits << endl;// 打印刚刚读取的内容

bitset与位操作符

std::bitset 类在 C++ 中为处理固定大小的位序列提供了方便。

使用 std::bitset 时,你可以直接对其应用位操作符,如按位与 (&)、按位或 (|)、按位异或 (^)、按位取反 (~)、左移 (<<) 和右移 (>>)。

下面是一些使用 std::bitset 和位操作符的示例:

#include <iostream>  
#include <bitset>  
  
int main() {  
    // 创建两个8位的bitset对象  
    std::bitset<8> b1(42); // 00101010  
    std::bitset<8> b2(25); // 00011001  
  
    // 使用位操作符  
    std::bitset<8> b3 = b1 & b2;    // 按位与: 00001000  
    std::bitset<8> b4 = b1 | b2;    // 按位或: 00111011  
    std::bitset<8> b5 = b1 ^ b2;    // 按位异或: 00110011  
    std::bitset<8> b6 = ~b1;        // 按位取反: 11010101  
    std::bitset<8> b7 = b1 << 2;    // 左移两位: 10101000  
    std::bitset<8> b8 = b2 >> 1;    // 右移一位: 00001100  
  
    // 输出结果  
    std::cout << "b1: " << b1 << std::endl;  
    std::cout << "b2: " << b2 << std::endl;  
    std::cout << "b3 (b1 & b2): " << b3 << std::endl;  
    std::cout << "b4 (b1 | b2): " << b4 << std::endl;  
    std::cout << "b5 (b1 ^ b2): " << b5 << std::endl;  
    std::cout << "b6 (~b1): " << b6 << std::endl;  
    std::cout << "b7 (b1 << 2): " << b7 << std::endl;  
    std::cout << "b8 (b2 >> 1): " << b8 << std::endl;  
  
    return 0;  
}

在这个示例中:

  • b1 和 b2 是两个 std::bitset<8> 对象,分别初始化为十进制数 42 和 25 的二进制表示。
  • b3 是 b1 和 b2 的按位与结果。
  • b4 是 b1 和 b2 的按位或结果。
  • b5 是 b1 和 b2 的按位异或结果。
  • b6 是 b1 的按位取反结果。
  • b7 是 b1 左移两位的结果。
  • b8 是 b2 右移一位的结果。

输出将会是这些操作的二进制结果。

注意,当使用位操作符时,结果的位数与操作数的位数相同。如果左移或右移操作导致某些位丢失,那么这些位将被简单地丢弃。同样,如果左移操作导致在右侧产生新的位,那么这些位将被设置为 0。

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

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

相关文章

近屿智能独家发布行业领先的AIGC学习路径图

近日来“人工智能即将取代大量人类工作”的话题愈演愈烈&#xff0c;在CCTV-13的《两会你我他》访谈节目中&#xff0c;众多专家也围绕这一议题展开了深入的讨论&#xff0c;AI不会取代你的工作&#xff0c;会取代你的是懂AI技术的人。李强总理在访谈中也强调了推动"人工智…

【NTN 卫星通信】卫星辅助补充下行数据应用场景

1 卫星辅助下行数据场景概述 在乡村地区向地面接入网覆盖欠佳或无线电条件(例如山谷地区)的用户提供无线接入网可能无法提供所需的服务性能。   增加补充下行数据容量(例如由NTN提供)将有助改善服务性能和QoE&#xff0c;例如支援与视讯消费有关的流量不对称。因此&#xff0…

SpringBoot:自定义线程池配置类

文章目录 一、前言二、案例展示1、初始版本2、代码审核意见和优化建议3、潜在问题和风险4、优化建议5、优化后的代码 三、具体使用 一、前言 有时候我们在项目中做一些长链路的跑批任务时&#xff0c;基于Springboot项目的定时任务&#xff0c;我们可以指定一个自定义的线程配…

C-偶遇行军蚁(遇到过的题,做个笔记)

我的代码: 思路就是把每一行看成一个字符串&#xff0c;然后逐渐增加字符就行 #include <iostream> #include <vector> using namespace std; int main() {string s;int n;cin >> n; //读入行数cin >> s; //读入字符串vector<string>arr(n…

一起来从Solidworks中导出URDF模型

这个博客是用来记录关于【从Solidworks中导出URDF模型】的学习历程&#xff1a; 相关课程链接见&#xff1a;如何从Solidworks导出URDF模型 • 古月 (guyuehome.com) 下面让我们一起开始吧&#xff01;&#xff01;&#xff01; 1. sw_urdf_exporter插件介绍 插件下载链接&…

共享社会经济路径(SSP1-5)中国及分省人口预估数据库_v2

v1数据集&#xff1a; 在共享社会经济路径&#xff08;SSPs&#xff09;全球框架下&#xff0c;根据本地化人口和经济参数&#xff0c;采用人口-发展-环境&#xff08;PDE&#xff09;模型&#xff0c;构建2020-2100年SSPs人口格点数据&#xff1b;采用柯布-道格拉斯&#xff…

基于STM32的汽车防窒息系统

文章目录 基于STM32的汽车防窒息系统系统简介材料展示视频制作硬件连接原理图PCB实物图GSM模块使用GSM模块代码 SGP30模块SGP30模块代码 步进电机驱动步进电机代码 其他模块主逻辑代码 总结 基于STM32的汽车防窒息系统 系统简介 随着社会的发展目前汽车的流行&#xff0c;汽车大…

vSAN vs SmartX 超融合:BI 数仓跑批效率对比测试

在《VMware 与 SmartX 分布式存储缓存机制浅析与性能对比》中&#xff0c;我们分析了 vSAN 7 缓存击穿的问题及其原因。近期&#xff0c;某金融用户在进行数据仓库分布式存储选型时&#xff0c;同样遭遇了测试过程中 vSAN 出现缓存击穿而难以完成全量跑批任务的问题。随后&…

安卓Android 架构模式及UI布局设计

文章目录 一、Android UI 简介1.1 在手机UI设计中&#xff0c;坚持的原则是什么1.2 安卓中的架构模式1.2.1 MVC (Model-View-Controller)设计模式优缺点 1.2.2 MVP(Model-View-Presenter)设计模式MVP与MVC关系&#xff1a; 1.2.3 MVVM(Model—View—ViewModel ) 设计模式1.2.4 …

ssm018简易版营业厅宽带系统+jsp

营业厅宽带系统设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本营业厅宽带系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间…

群晖NAS使用Docker部署大语言模型Llama 2结合内网穿透实现公网访问本地GPT聊天服务

文章目录 1. 拉取相关的Docker镜像2. 运行Ollama 镜像3. 运行Chatbot Ollama镜像4. 本地访问5. 群晖安装Cpolar6. 配置公网地址7. 公网访问8. 固定公网地址 随着ChatGPT 和open Sora 的热度剧增,大语言模型时代,开启了AI新篇章,大语言模型的应用非常广泛&#xff0c;包括聊天机…

新发现!科学家最新成果:补充类“原知因起源金”物质可延长寿命23%

近日&#xff0c;美哥伦比亚大学Vijay Yadav团队在《Science》发布了一项重磅级成果&#xff1a;通过补充一种特殊氨基酸&#xff08;带有磺酸基团的全能抗衰物质&#xff09;&#xff0c;竟然惊人地将实验动物的寿命延长了23%。 而其背后的机制&#xff0c;与早已火爆电商圈的…

Git命令(1)[删除,恢复与移动]

文章目录 1.删除文件1.1命令----rm <filename>1.2命令----git rm <filename>1.1命令----git rm <filename> -f 2.恢复文件2.1命令----git restore <filename>2.1命令----git restore --staged <filename> 3.重命名文件3.1命令----mv <oldFile…

javaweb学习(day10-服务器渲染技术)

一、基本介绍 1.前言 目前主流的技术是 前后端分离 (比如: Spring Boot Vue/React)JSP 技术使用在逐渐减少&#xff0c;但使用少和没有使用是两个意思&#xff0c;一些老项目和中小公司还在使用 JSP&#xff0c;工作期间&#xff0c;你很有可能遇到 JSPJSP 使用在减少(但是现…

分布式唯一ID 雪花算法

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;算法分析与设计 ⛺️稳中求进&#xff0c;晒太阳 算法具体介绍 雪花算法是 64 位 的二进制&#xff0c;一共包含了四部分&#xff1a; 1位是符号位&#xff0c;也就是最高位&#xff0c;…

基于Weibull、Beta、Normal分布的风、光、负荷场景生成及K-means场景削减方法

目录 一、主要内容&#xff1a; 二、代码运行效果&#xff1a; 三、Weibull分布与风机风速&#xff1a; 四、Beta分布与光伏辐照度&#xff1a; 五、Normal分布与电负荷&#xff1a; 六、K-means聚类算法&#xff1a; 七、完整代码数据下载&#xff1a; 一、主要内容&am…

vue3的动态组件

动态组件可以根据响应式变量动态的渲染不同的组件&#xff0c;目前是通过Vue 的 元素和特殊的 is attribute 实现的&#xff1a; <component :is"tabs[currentTab]"></component>:is 的值可以是以下几种&#xff1a; 被注册的组件名 导入的组件对象 你…

211基于matlab的多类结构动力学

基于matlab的多类结构动力学&#xff0c;凸轮机构、双凸轮、弦振动模拟、阻尼振动 、四连杆机构 、套杆运动 、三根弹簧作用的振子。程序已调通&#xff0c;可直接运行。 211 matlab 结构动力学 根弹簧作用的振子 - 小红书 (xiaohongshu.com)

蓝桥杯第793题——排水系统

题目描述 对于一个城市来说&#xff0c;排水系统是极其重要的一个部分。 有一天&#xff0c;小 C 拿到了某座城市排水系统的设计图。排水系统由 n 个排水结点&#xff08;它们从 1∼n 编号&#xff09;和若干个单向排水管道构成。每一个排水结点有若干个管道用于汇集其他排水…

SSM框架学习——工厂模式、Spring核心容器与Bean

工厂模式、核心容器与Spring Bean 工厂模式 工厂模式是Java中常用的一种设计模式&#xff0c;这种类型的设计模式属于创建型模式。说白了在代码层面就是取消了new的使用。 工厂模式有三种&#xff1a; 简单工厂模式工厂方法模式抽象工厂模式 举个例子&#xff0c;我们去买…