C++ 位集(bitset)简介

原文链接:点我传送 (无法访问)
原文作者:Utkarsh Trivedi

难度:简单
更新日期:2018-9-4

位集(bitset)是一组布尔值,但是每个布尔值都不会单独存储,而是通过优化,使得每个布尔仅占用1位空间,所以位集占用的空间要比bs[N]vector bs(N)要小。但是,位集的不足在于在编译时N必须要确定,即N是一个常量。vector和动态数组就不会有这个麻烦。

由于位集以压缩方式存储相同的信息,因此对位集的操作比对数组和向量的操作要快。我们可以借助数组索引运算符[]分别访问位集的每个位,即bs[3]就像简单数组一样显示位集bs的索引3处的位。请记住,bitset的索引从后开始,即10110,0位于第0和第3索引,而1位于第1第2和第4索引。

我们可以通过构造函数使用整数和二进制字符串构造一个位集,如下面的代码所示。位集的大小在编译时是固定的,即无法在运行时更改。
为位集类定义的主要功能是运算符[],计数,大小,设置,重置等,下面的代码将对它们进行更多说明–

// C++演示位集的多种功能 
#include <bits/stdc++.h> 
using namespace std; 
  
#define M 32 
  
int main() 
{ 
    // bset1初始化默认全为0 
    bitset<M> bset1; 
  
    // bset2用20位初始化

    bitset<M> bset2(20); 
  
    // bset3用特定的二进制字符串进行初始化
    bitset<M> bset3(string("1100")); 
  
    // 打印位集
    cout << bset1 << endl; // 00000000000000000000000000000000 
    cout << bset2 << endl; // 00000000000000000000000000010100 
    cout << bset3 << endl; // 00000000000000000000000000001100 
    cout << endl; 
  
    // 声明set8具有8位容量
  
    bitset<8> set8; // 00000000 
  
    // 更改索引为1的位置(也可以叫第6个?)
    set8[1] = 1; // 00000010 
    set8[4] = set8[1]; // 00010010 
    cout << set8 << endl; 
  
    // count函数返回这个位集有多少个1
    int numberof1 = set8.count(); 
  
    // size函数返回位集的总大小
    // 所以二者的差值就是位集有多少个0
    int numberof0 = set8.size() - numberof1; 
  
    cout << set8 << " has " << numberof1 << " ones and "
         << numberof0 << " zeros\n"; 
  
    // test返回位集中的一个位是1还是0
    cout << "bool representation of " << set8 << " : "; 
    for (int i = 0; i < set8.size(); i++) 
        cout << set8.test(i) << " "; 
  
    cout << endl; 
  
    // any函数
    // 至少有一位为真,则返回真
    if (!set8.any()) 
        cout << "set8 has no bit set.\n"; 
  
    if (!bset1.any()) 
        cout << "bset1 has no bit set.\n"; 
  
    // none函数
    // 如果全为0,则返回真
    if (!bset1.none()) 
        cout << "bset1 has some bit set\n"; 
  
    // bset.set()把位集全设为1
    cout << set8.set() << endl; 
  
    // bset.set(pos, b)使得bset[pos] = b 
    cout << set8.set(4, 0) << endl; 
  
    // bset.set(pos)使得bset[pos] = 1  也就是说默认为1
    cout << set8.set(4) << endl; 
  
    // reset函数让所有位为0
    cout << set8.reset(2) << endl; 
    cout << set8.reset() << endl; 
  
    // flip函数0与1互换
    cout << set8.flip(2) << endl; 
    cout << set8.flip() << endl; 
  
    // 用位集将十进制转化为二进制
    int num = 100; 
    cout << "\nDecimal number: " << num 
         << "  Binary equivalent: " << bitset<8>(num); 
  
    return 0; 
} 

输出:

00000000000000000000000000000000
00000000000000000000000000010100
00000000000000000000000000001100

00010010
00010010 has 2 ones and 6 zeros
bool representation of 00010010 : 0 1 0 0 1 0 0 0 
bset1 has no bit set.
11111111
11101111
11111111
11111011
00000000
00000100
11111011

Decimal number: 100 Binary equivalent: 01100100

对于位设置,定义了复位和翻转功能。设置函数设置(1)如果未提供任何参数,则设置bitset的所有位,否则设置其位置作为参数给出的位。以相同的方式,如果没有参数调用它们,复位和翻转也将起作用,它们将在整个位集上执行其操作;如果提供某个位置作为参数,则它们仅在该位置上执行操作。
对于位集,所有按位运算符都是重载的,即它们可以直接应用于位集,而无需任何转换或转换,主要的重载运算符是|==!=和移位运算符<>,这使对位集的操作变得容易。
下面的代码显示了上面运算符的使用。

// C++展示位集的操作符
#include <bits/stdc++.h> 
using namespace std; 
  
int main() 
{ 
    bitset<4> bset1(9); // bset1 是 1001 
    bitset<4> bset2(3); // bset2 是 0011 
  
    // 比较运算符
    cout << (bset1 == bset2) << endl; // false 0 
    cout << (bset1 != bset2) << endl; // true  1 
  
    // 位运算符 赋值运算符
    cout << (bset1 ^= bset2) << endl; // 1010 
    cout << (bset1 &= bset2) << endl; // 0010 
    cout << (bset1 |= bset2) << endl; // 0011 
  
    // 左右移位
    cout << (bset1 <<= 2) << endl; // 1100 
    cout << (bset1 >>= 1) << endl; // 0110 
  
    // ~
    cout << (~bset2) << endl; // 1100 
  
    // 位运算符
    cout << (bset1 & bset2) << endl; // 0010 
    cout << (bset1 | bset2) << endl; // 0111 
    cout << (bset1 ^ bset2) << endl; // 0101 
} 

输出:

0
1
1010
0010
0011
1100
0110
1100
0010
0111
0101
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值