C++ bitset库的使用

  • bitset
  • bitset初始化
    • 1.构造
    • 2.整数初始化
    • 3.字符串初始化
    • 4.自定义符号初始化
  • 常用
    • 1. == 和 !=
    • 2. test 获得指定位的值
    • 3. size 获得长度
    • 4. all, any, none
    • 5. count 计算1的个数
    • 6. set 设为true/1
    • 7. reset 设为false/0
    • 8. flip 取反
    • 9. to_string 转字符串
    • 10. to_ulong,to_ullong 转整数
  • 操作符

bitset

文档:https://zh.cppreference.com/w/cpp/utility/bitset
bitset<N> 表示一个N位的固定大小的序列,可以用于整数和字符串的相互转换
例:5在bitset<8> temp中存储为 [0000 0101] (temp[0]=0,temp[8]=1)
采用逆向存储(低位存放高阶,高位存放低阶),并且采用的是补码
空间长度不足正整数自动补0,负整数自动补1

满足:
1.可复制构造
2.可复制赋值

头文件

#include <bitset>

bitset初始化

constexpr unsigned int N=8;

1.构造

空构造

bitset<N> temp(); // [0,0,0,0, 0,0,0,0]

自身构造,长度必须相同

bitset<N> temp1(string("00001001"));
bitset<N> temp2(temp1); // [0,0,0,0, 1,0,0,1]
// 或者
// bitset<N> temp2=temp1; // [0,0,0,0, 1,0,0,1]

2.整数初始化

bitset(N) temp((unsigned long long)(9));  // [0,0,0,0, 1,0,0,1]
bitset(N) temp((unsigned long long)(-9)); // [1,1,1,1, 0,1,1,1]
bitset(N) temp(0b11110111); // [1,1,1,1, 0,1,1,1]

如果初始化的整数长度大于N(长度不足):
数字19的二进制: 0001 0011,若bitset长度不足,将会保存保存低阶部分。

bitset<4> temp(19)  // [0,0,1,1]

3.字符串初始化

字符串初始化采用从左到右复制,靠右对齐,不足自动补0,支持string和char[]。

bitset<N> temp(string("00001001")); // [0,0,0,0,1,0,0,1]
char ch = "01001101;
bitset<N> temp(ch)); // [0,1,0,0,1,1,0,1]// 字符串长度小于N
bitset<N> temp(string("1001")); // [0,0,0,0,1,0,0,1]
char ch = "1001101;
bitset<N> temp(ch)); // [0,1,0,0,1,1,0,1]

字符串初始化比较复杂,分为多种情况,正常来说我们自己写代码不会出现长度对齐的情况。

字符串复制是从数组下标从0开始。

1.指定读取字符串的开始下标
bitset<N> temp(string, num1),num1为开始下标,且0≤num<str.length(),向右对齐
用例1:

bitset<N> temp(string("111100"),0); // [0,0,1,1, 1,1,0,0]
bitset<N> temp(string("111100"),1); // [0,0,0,1, 1,1,0,0]
bitset<N> temp(string("111100"),2); // [0,0,0,0, 1,1,0,0]
bitset<N> temp(string("111100"),3); // [0,0,0,0, 0,1,0,0]
bitset<N> temp(string("111100"),4); // [0,0,0,0, 0,0,0,0]
bitset<N> temp(string("111100"),5); // [0,0,0,0, 0,0,0,0]
bitset<N> temp(string("111100"),6); // [0,0,0,0, 0,0,0,0]

用例2:开始下标超过字符串长度,将会报错 terminate called after throwing an instance of ‘std::out_of_range’ what(): bitset::bitset: __position (which is 8) > __s.size() (which is 6)

bitset<N> temp(string("111100"),7); // terminate called after throwing an instance of 'std::out_of_range'  what():  bitset::bitset: __position (which is 8) > __s.size() (which is 6)

2.指定字符串读取长度
biteset<N> temp(str, num1, num2),num1为开始下标,num2为读取长度。

用例1:从下标3开始读,读2个字符,得到"10",然后右对齐

bitset<N> temp(string("11110000"),3,2);  // [0,0,0,0,0,0,1,0]

用例2:从下标3开始读,指定读取长度超过字符串长度

// 临界值
bitset<N> temp(string("11110000"),3,5);  // [0,0,0,1,0,0,0,0]
// 超过字符串长度
bitset<N> temp(string("11110000"),3,10); // [0,0,0,1,0,0,0,0]

可以看出 num2 超过字符串长度不会对 bitset 的结果产生影响, 我认为应该是字符串读取长度被强制更改为 min(str.length()-num1, num2)

3.字符串长度大于 bitset数组长度
用例1:仅初始化,bitset按下标从左到右保存string

bitset<4> temp(string("10010")); // [1,0,0,1]

用例2:指定读取字符串的开始下标

bitset<4> temp(string("1010010"),2); // [1,0,0,1]

用例3:指定读取字符串的开始下标和读取长度

bitset<4> temp(string("10100100001"),2,5); // [1,0,0,1]

4.自定义符号初始化

1.bitset<N> temp(char[], length, char_zero,char_one);
length表示输入字符串读取长度
用例1:从字符串中读取长度为1的字符,字符’0’设为0,字符’1’设为1

bitset<8> temp("10010101",1,'0','1'); // [0,0,0,0, 0,0,0,1]
bitset<8> temp("00010101",1,'0','1'); // [0,0,0,0, 0,0,0,0]

用例2:从字符串中读取长度为8的字符,字符’a’设为0,字符’b’设为1

bitset<8> temp("abaabbba",8,'a','b'); // [0,1,0,0, 1,1,1,0]

用例3:喜闻乐见的字符串长度问题,length超过字符串长度就会报错,仅超过bitset的的长度依旧是保留高位

bitset<8> temp("abaa",8,'a','b'); // terminate called after throwing an instance of 'std::invalid_argument' what():  bitset::_M_copy_from_ptr
bitset<3> temp("abaa",3,'a','b'); // [0,1,0]
bitset<3> temp("abaa",8,'a','b'); // [0,1,0]

2.bitset<N> temp(string,num1,num2,char_one,char_zero);
这个和上面的string的用法一样,不做解释,string(str)和str不是一个东西,后者是char[],这两个的使用方法不一样

常用

1. == 和 !=

可以比较两个长度相同的bitset所有位是否相等

bitset<4> temp1(-3);
bitset<4> temp2(string("1101")); // 正数13,负数-3
cout << (temp1==temp2) <<endl;  // 1
cout << (temp1!=temp2) <<endl;  // 0

也可以与数字比较

bitset<4> temp1(-3);
cout << (temp1==-3) <<endl;
cout << (temp1!=13) <<endl;bitset<4> temp2(string("1101")); // 正数13,负数-3
cout << (temp2==-3) <<endl;  // 1
cout << (temp2!=13) <<endl;  // 0

2. test 获得指定位的值

temp.test[i] 返回temp[i]的值,与temp[i]不同的是,如果 i 不是合法位置,test(i)会抛异常 std::out_of_range
这里的i是从低阶到高阶,也就是数组最后一位是最低阶,test(0)会得到bitset[N-1]的值

bitset<N> temp(0b10101110);
cout << temp.test(0) <<endl; // 0
cout << temp.test(1) <<endl; // 1
cout << temp.test(2) <<endl; // 1
cout << temp.test(3) <<endl; // 1
cout << temp.test(4) <<endl; // 0
cout << temp.test(5) <<endl; // 1
cout << temp.test(6) <<endl; // 0
cout << temp.test(7) <<endl; // 1
cout << temp.test(8) <<endl; //terminate called after throwing an instance of 'std::out_of_range' what():  bitset::test: __position (which is 8) >= _Nb (which is 8)
cout << temp.test(-1) <<endl; // terminate called after throwing an instance of 'std::out_of_range' what():  bitset::test: __position (which is 4294967295) >= _Nb (which is 8)

3. size 获得长度

返回 bitset 的位数

cout << bitset<N>().size(); // 8

4. all, any, none

all:是否全为true/1
any:是否存在true/1
none:是否不存在true/1

bitset all any
0000 0 0
0101 0 1
1111 1 1

5. count 计算1的个数

返回bitset中true/1的个数

cout << bitset<N>(b11111000).count(); // 5

6. set 设为true/1

两种用法:
1.set():设置所有位为true/1
2.set(i):指定阶设为true/1,i是要设置的位(从最低阶到最高阶/从最后一个到第一个)
这里的i是从低阶到高阶,也就是数组最后一位是最低阶,set(0)令bitset[N-1]=1,如果 i 不是合法位置,set(i)会抛异常 std::out_of_range

cout << bitset<N>(0b11111000).set(0) << endl; // 11111001
cout << bitset<N>(0b11111000).set()  << endl; // 11111111

7. reset 设为false/0

两种用法:
1.reset ():设置所有位为false/0
2.reset (i):指定阶设为false/0,i是要设置的位(从最低阶到最高阶/从最后一个到第一个)
这里的i是从低阶到高阶,也就是数组最后一位是最低阶,reset(0)令bitset[N-1]=0,如果 i 不是合法位置,reset(i)会抛异常 std::out_of_range

cout << bitset<N>(0b11111000).reset(3) << endl; // 11110000
cout << bitset<N>(0b11111000).reset()  << endl; // 00000000

8. flip 取反

两种用法:
1.flip():设置所有位为取反
2.flip(i):指定阶取反,i是要设置的位(从最低阶到最高阶/从最后一个到第一个)
这里的i是从低阶到高阶,也就是数组最后一位是最低阶,flip(0)令bitset[N-1]=0,如果 i 不是合法位置,flip(i)会抛异常 std::out_of_range

cout << bitset<N>(0b11111000).flip(4) << endl; // 11101000
cout << bitset<N>(0b11111000).flip()  << endl; // 00000111

9. to_string 转字符串

两种用法:
1.to_string()

cout << bitset<N>(      0b111111000).  to_string() << endl; // 11111000
cout << bitset<N>(       "111111000"). to_string() << endl; // 11111100
cout << bitset<N>(string("111111000")).to_string() << endl; // 11111100

2.to_string(ch_zero)和to_string(ch_zero,ch_one)

cout << bitset<N>(      0b111111000).  to_string('*') << endl; // 11111***
cout << bitset<N>(       "111111000"). to_string('*') << endl; // 111111**
cout << bitset<N>(string("111111000")).to_string('*') << endl; // 111111**cout << bitset<N>(      0b111111000).  to_string('-','+') << endl; // +++++---
cout << bitset<N>(       "111111000"). to_string('-','+') << endl; // ++++++--
cout << bitset<N>(string("111111000")).to_string('-','+') << endl; // ++++++--

10. to_ulong,to_ullong 转整数

cout << bitset<N>(0b111111000).to_ulong() << endl;
cout << bitset<N>("111111000").to_ulong() << endl; cout << bitset<N>(0b111111000).to_ullong() << endl;
cout << bitset<N>("111111000").to_ullong() << endl;

储存到带符号变量中要考虑到N的长度,例如下面这样得到的都是-1,因为short的长度是16位,如果把N改成15,那么num得到的数会是32767(2的15次方-1)

constexpr int N = 16;
bitset<N> temp1("1111111111111111");
bitset<N> temp2(-1);
bitset<N> temp3(0b1111111111111111);
for (auto i:{temp1,temp2,temp3}){short num = i.to_ulong();cout << num << endl; //-1
}

操作符

操作符 描述
<< 返回新的左移结果
<<= 返回当前对象左移后的结果
>> 返回新的右移结果
>>= 返回当前对象右移后的结果
&=
|=
^& 异或
~

<<

bitset<4> temp("1001");
bitset<4> temp2 = temp<<1;
cout << temp << endl; // 1001
cout << temp2 <<endl; // 0010

<<=

bitset<4> temp("1001");
bitset<4> temp2 = temp<<=1;
cout << temp <<endl; // 0010
cout << temp2 <<endl; // 0010

>>

bitset<5> temp1("11111"); // 11111
bitset<5> temp2(-1);      // 11111
bitset<5> temp3(0b11111); // 11111
cout << (temp1>>1) <<endl;// 01111
cout << (temp2>>1) <<endl;// 01111
cout << (temp3>>1) <<endl;// 01111

与、或、异或及非

cout << (bitset<4>("1011") ^= bitset<4>("0101")) << endl; // 1110
cout << (bitset<4>("1011") |= bitset<4>("0101")) << endl; // 1111
cout << (bitset<4>("1011") &= bitset<4>("0101")) << endl; // 0001
cout << ~bitset<4>("1011") << endl; // 0100

C++ bitset的使用相关推荐

  1. 算法复习——bitset(bzoj3687简单题)

    题目: Description 小呆开始研究集合论了,他提出了关于一个数集四个问题: 1.子集的异或和的算术和. 2.子集的异或和的异或和. 3.子集的算术和的算术和. 4.子集的算术和的异或和.   ...

  2. bitset类型, 标准库类型

    C++ primer 17.2 bitset类型, 标准库类型 1 使得位运算更容易实现, 并且能够处理超过最长整型大小的位集合. bitset定义在bitset中 定义和初始化bitset 1 bi ...

  3. 2016多校赛2 A 数学推公式 E 极角排序,组合数(待补) L dp+bitset优化

    2016 Multi-University Training Contest 2 A - Acperience 题意:给出w[],求S((w[i]-aB[i])^2)的最小值(B[i]为1或-1). ...

  4. bitset HDU6515 Coding Problem

    Coding Problem [ HDU - 6515 ] 题目大意:给你一个字符串,每个字母的ASCII二级制颠倒过来组成一个01数组. 然后这个数组每六位组成一个数字的ASCII输出 一道模拟题, ...

  5. 【JZOJ5064】【GDOI2017第二轮模拟day2】友好城市 Kosarajo算法+bitset+ST表+分块

    题面 在Byteland 一共有n 座城市,编号依次为1 到n,这些城市之间通过m 条单向公路连接. 对于两座不同的城市a 和b,如果a 能通过这些单向道路直接或间接到达b,且b 也能如此到达a,那么 ...

  6. bitset优化+滚动优化dp ----- 2021牛客多校第8场 F Robot

    题目大意: 就是给你一个大小为n∗mn*mn∗m的矩阵,里面有障碍物,每次询问给你一个机器人,以及机器人的起始位置,问你这个机器人能否从起点到终点 机器人有3种类型 只能往右走 只能往下走 可以往右走 ...

  7. 点分治问题 ----------- 2017杭州CCPC E.Master of Subgraph[bitset+点分治]

    题目链接 题目大意: 就是给你一颗树,树上每个点都有自己的权值,问你这棵树是否存在一棵子树,子树的权值和是[1,m][1,m][1,m]里面的,对于[1,m][1,m][1,m]里面的数,如果出现过就 ...

  8. 【每日训练】2020/11/8(规律 + 二进制、单调栈 + 前缀和,后缀和、bitset + 枚举)

    整理的算法模板合集: ACM模板 目录 1. NC 打铁的箱子(规律 + 二进制) 2. NC 最优屏障(单调栈 + 前缀和,后缀和) 3. CF993C Careful Maneuvering(bi ...

  9. P6134 [JSOI2015]最小表示(拓扑排序递推 + bitset优化,可达性统计变种)

    整理的算法模板合集: ACM模板 P6134 [JSOI2015] 题目要求删除一条边整个图的连通性是不受影响的,也就是说如果我们要删除边(x,y)(x,y)(x,y),删除以后整个图的连通性不受影响 ...

  10. 解题报告:简单瞎搞题(bitset的应用)

    题目链接:https://ac.nowcoder.com/acm/contest/5556/E 输入 5 1 2 2 3 3 4 4 5 5 6 输出 26 备注: 1≤n,li,ri≤1001 ≤ ...

最新文章

  1. 如何设置电脑自动锁屏_如何把视频设置为 iPhone 动态锁屏壁纸?
  2. Python中的张量分解
  3. python网上编程课程-程序设计入门—Python
  4. 防火墙认证的类型——Vecloud
  5. 十六个 HTML,CSS,jQuery,WordPress等快速启动项目样板
  6. dfs hdfs 修改文件名称_CDH6.3.2生产更换HDFS 数据目录
  7. golang的panic用法
  8. Yii 文件上传类的使用
  9. 多重背包O(N*V)算法详解(——使用单调队列)
  10. 算法 Tricks(六)— if 条件分支的简化
  11. ie8以ie7方式解析
  12. VS2017安装过程电脑突然关机
  13. 功能测试分析和测试用例编写模板
  14. 2022年 接口测试高频面试题及答案
  15. Dazdata BI之PDF魔幻输出
  16. Excel数值函数(4):对指定条件的单元格求和
  17. Python基础知识——变量与运算符
  18. 又一神作,Alibaba“M8级”大老总结微服务与事件驱动架构启蒙手册
  19. Android闹钟制作过程图,小学闹钟手工制作步骤详解(配图)
  20. Nginx是什么??

热门文章

  1. 概率图模型--最大后验概率状态推理MAP
  2. meso-四(邻烷氧基苯基)卟啉合钴(meso-T(2-ROP)PCo);meso-四-(N-苄基)吡碇基卟啉锌(ZnTBPyP);离子型锰卟啉化合物[MnTTMAPP][PF6]5齐岳供应
  3. norflash的操作
  4. PostgreSQL向量计算插件——vops
  5. python数据库选择
  6. Python不换行输出
  7. ThinkPad E40取消FN功能键设置
  8. Java --- JVM动态链接与方法调用
  9. 【面试】被问“怎么进行接口测试”的知识点大全
  10. “进大厂大半年,每个月都想走!”大公司 VS 小公司到底该如何选择?