C++ bitset

C++ 中的 std::bitset 是一个固定大小的二进制位集合,每个元素只能是 0 或 1。它的大小在编译时就已经确定,可以在定义时指定大小,也可以使用默认构造函数创建一个空的 bitset,然后通过 resize() 方法重新指定大小。bitset 同时支持位运算和逻辑运算,并提供了许多实用的方法。

下面是一些 bitset 的常用操作:

  1. 创建一个大小为 10 的 bitset,所有位都设置为 0:
std::bitset<10> b;
  1. 创建一个大小为 20 的 bitset,并将第 2、4、6 位设置为 1:
std::bitset<20> b("01010100000000000000");
  1. 访问第 i 位:
std::bitset<10> b("1100110010");
bool bit = b[3];  // 获取第 3 位
  1. 从指定位置开始获取长度为 n 的子段:
std::bitset<10> b("1100110010");
std::bitset<3> sub = b.to_ulong<3>(2);  // 从第 2 位开始获取 3 位
  1. 获取 bitset 中 1 的个数:
std::bitset<10> b("1100110010");
int count = b.count();  // 获取 1 的个数
  1. 将 bitset 中的所有位都设置为 1:
std::bitset<10> b("1100110010");
b.set();  // 将 b 中所有位都设置为 1
  1. 将指定位置的位设置为 1:
std::bitset<10> b("1100110010");
b.set(5);  // 将第 5 位设置为 1
  1. 按位取反:
std::bitset<10> b("1100110010");
b.flip();  // 将 b 中所有位都按位取反
  1. 按位与运算:
std::bitset<10> b1("1100110010");
std::bitset<10> b2("1111000111");
std::bitset<10> result = b1 & b2;  // 对 b1 和 b2 中的所有位进行按位与运算
  1. 按位或运算:
std::bitset<10> b1("1100110010");
std::bitset<10> b2("1111000111");
std::bitset<10> result = b1 | b2;  // 对 b1 和 b2 中的所有位进行按位或运算
  1. 按位异或运算:
std::bitset<10> b1("1100110010");
std::bitset<10> b2("1111000111");
std::bitset<10> result = b1 ^ b2;  // 对 b1 和 b2 中的所有位进行按位异或运算

std::bitset 作为二进制位集合,可以用于许多场景,如压缩数据、位图存储等。在实际编程中,应充分利用 std::bitset 的特性,提高代码效率和可读性。


other



bitset是比特集合,用于位运算等操作。

固定长度,支持随机访问。同替他模板类一样,bitset的使用方法和其他模板类差别不大

bitset b b有n位,被默认设置位0,n必须为常量表达式

bitset b(u) b是unsigned long long 的低n位比特串拷贝,如果超出u的位数,剩余的被设置为0

//有时候可能将字符串与比特串之间互相转换,可用到下面的构造函数

bitset b(s, pos, m, zero, one)

//b是string s 从pos位开始m个字符的拷贝s只能包含zero/one, 否则会抛出一个invalid_arguement异常。
字符在b中分别保存位zero one. pos默认值为0, m默认为std::string::npos,zero默认为’0’, one 默认为’1’

bitset b(cp, pos, m, zero, one)

//同上面的构造函数相同,但是从cp指向的字符数组中拷贝字符。如果没有提供m, 则cp必须指向一个字符串。如果提供了m,则从cp开始必须至少有m个zero/one字符

//注意:上述两个构造函数,即接受string或者字符指针的构造函数是explicit的。在新标准中增加了为0和1指定其他字符的功能

1.演示

#include
#include
#include
using namespace std;

int main()
{
const unsigned bit_num = 13;
bitset<13> b1 (0xbeef);
for(int i = bit_num -1;i>=0;–i)
cout << b1[i];
cout << endl;
bitset<20> b2 (0xbeff);

for(int i= 20-1;i>=0;--i)
    cout << b2[i];
return 0;

}

1.运行结果

1111011101111
00001011111011111111
2.演示

#include
#include
using namespace std;

int main()
{
string bit_string = “1001001100”;
bitset<10> b1 (bit_string); // b1 is 1001001100
bitset<4> b2(bit_string,5,4,‘0’,‘1’);
for(int i = 4-1;i>=0;–i){
cout << b2[i];
}
cout << endl;
bitset<4> b3(bit_string,bit_string.length()-4);
for(int i=4-1;i>=0;–i){
cout << b3[i];
}
return 0;
}

2.运行结果

0110
1100
可以看出,类似头迭代器和超尾迭代器的规则在bitset的构造时候依然适用

先介绍一些概念

置位:将某一位设置为1

复位:将某一位设置为0

bitset方法

//关于bitset的状态

.any() 是存在置位的二进制返回true

.none() 不存在置位的二进制返回true

.all() 所有位都置位返回true

.count() 返回置位的位数

.size() 一个constexpr函数,返回位数

.test(pos) pos位为真返回true

//关于设置bitset状态的函数

.set(pos,v) 设置pos位为v,v默认值为真值

.set() 无实参的情况下将所有位置位

.reset(pos) 复位pos位

.reset() 无实参的情况下复位所有位

.flip(pos) 切换pos位

.filp() 无实参的情况下切换所有位

b[pos] 下标访问

//其它功能

返回一个unsigned long / unsigned long long值,如果b中位模式不能放入指定的结果类型,抛出一个overflow_error异常

.to_ulong()

.to_ullong()

返回一个true为one flase为zero的字符串默认为’1’, ‘0’

.to_string(zero, one)

os << b 将b中的二进制位打印到流os

is >> b 从is流中输入二进制位

3.演示

用一个bitset来存放10人的成绩及格状况

#include
#include
#include
#define grade_table GT
using namespace std;

int main()
{
const unsigned stu_num = 10;
bitset<stu_num> grade_table;
cin >> grade_table;
if(GT.none()) //or !GT.any()
cout << “没有人及格” << endl;
else
cout << “一共有” << GT.count() << “人及格” << endl;
string bit_string = GT.to_string();
cout << ".to_string()返回了一个比特字符串: " << bit_string << endl;
cout << “老师大发慈悲,所有人都过了,好耶!” << endl;
GT.set();
cout << GT.to_string() << endl;
GT.reset(1);
cout << "但是一号小伙得罪了老师,老师没有给他过: " << GT.to_string() << endl;
cout << “不知道将这个比特串转换为无符号整形有什么意义的操作” << GT.to_ulong();
return 0;
}

3.运行结果

//输入
1001001100
//输出
一共有4人及格
.to_string()返回了一个比特字符串: 1001001100
老师大发慈悲,所有人都过了,好耶!
1111111111
但是一号小伙得罪了老师,老师没有给他过: 1111111101
不知道将这个比特串转换为无符号整形有什么意义的操作1021

可以看见,适用bitset比适用传统的位运算要方便许多,不用我们自己设计mask,不用进行令人头疼的位移操作,甚至输入输出比特串也经为我们定义好了。

其他

上面可以看出bitset为了泛型的功能,有着zero和one这两个东西,提供让用户自定义的功能

一些有趣的东西

4.演示

#include
#include
#include
using namespace std;

int main() {
const string str = “ynynyynnyn”;
bitset<10> b(str, 0, string::npos, ‘n’, ‘y’);
cout << b << endl;
cout << b.to_string(‘n’, ‘y’);
return 0;
}

4.运行结果

1010110010
ynynyynnyn

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值