STL特殊容器之bitset

一、概述

bitset构造出一个内含位(bit)或布尔(bool)值且大小固定的array。不能改变bitset内位的数量。这个参数由template参数决定的。如果需要一个可变长度的位容器,考虑使用vector<bool>。Class bitset定义于头文件<bitset>中,有一个template参数用来指定位的数量:

namespace std {
    template <size_t Bits>
    class bitset;
}

此处template的参数并不是一个型别,而是一个不带正负号的整数。

二、bitset操作函数

1. 生成、拷贝和销毁

bitset<bits>::bitset()
- default构造函数
- 生成一个bitset,所有值初始化为0

bitset<50> flags;    //flags: 000000...000000
bitset<bits>::bitset(unsigned long value)
- 产生一个bitset,以整数值value的二进制位作为初值
- 如果value的值太小,前面不足的位被设为0

bitset<50> flags(7);    //flags: 000000...000111

explicit bitset<bits>::bitset (const string& str)
bitset<bits>::bitset (const string& str, string::size_type str_idx)
bitset<bits>::bitset (const string& str, string::size_type str_idx, string::size_type str_num)
- 以上所有形式都用来初始化bitset,以字符串str或其子串加以初始化。
- 该字符串或者子串中只能包含字符'0'和'1'
- str_idx是str中用来初始化的第一个字符
- 如果省略str_num,从str_idx到str结束的所有字符都将用于初始化
- 若字符串中字符数量少于所需,前面多余的位置将被设为初值0
- 若字符串中字符数量多于所需,后面多余的位置将被忽略
- 如果str_idx>str.size(),抛出out_of_range异常
- 如果有字符非'0'非'1',抛出invalid_argument异常

bitset<50> flags(string("1010101"));    //flags: 000...0001010101
bitset<50> flags(string("1111000"),2,3);    //flags: 000...00000110

2. 非更易性操作

size_t bitset<bits>::size() const
- 返回位的个数

size_t bitset<bits>::count() const
- 返回“位值为1”的位个数

bool bitset<bits>::any() const
- 判断是否有任何位被设为1,有1返回true

bool bitset<bits>::none() const
- 判断是否所有位被设为0,全0返回true

bool bitset<bits>::test(size_t idx) const
- 判断idx位置上的位是否被设为1
- 如果idx >= size()则抛出out_of_range异常

bool bitset<bits>::operator == (const bitset<bits>& bits) const
- 判断*this和bits的所有位是否相等

bool bitset<bits>::operator != (const bitset<bits>& bits) const
- 判断*this和bits中是否有些位不相等

3. 更易性操作

bitset<bits>& bitset<bits>::set()
- 将所有位设为true(1)
- 返回更动后的bitset

bitset<bits>& bitset<bits>::set(size_t idx)
- 将位置idx上的位设为true(1)
- 返回更动后的bitset
- 如果idx超出范围,抛出out_of_range异常

bitset<bits>& bitset<bits>::set(size_t idx,int value)
- 根据value上的值设定idx位置的位值
- 返回更动后的bitset
- value将被当作boolean值处理。若为0,其值被设为false;其他的value值使得该位被设为true
- 如果idx超出范围,抛出out_of_range异常

bitset<bits>& bitset<bits>::reset()
- 将所有位设为false(0)
- 返回更动后的bitset

bitset<bits>& bitset<bits>::reset(size_t idx)
- 将位置idx上的位设为false(0)
- 返回更动后的bitset
- 如果idx超出范围,抛出out_of_range异常

bitset<bits>& bitset<bits>::flip()
- 反转所有位
- 返回更动后的bitset

bitset<bits>& bitset<bits>::flip(size_t idx)
- 反转位置idx上的位
- 返回更动后的bitset
- 如果idx超出范围,抛出out_of_range异常

bitset<bits>& bitset<bits>::operator ^= (const bitset<bits>& bits)
- 对每个位逐一进行异或运算
- 将*this中所有和“bits内数值为1的位”对应的位反转
- 返回更动后的bitset

bitset<bits>& bitset<bits>::operator |= (const bitset<bits>& bits)
- 对每个位逐一进行或运算
- 将*this中所有和“bits内数值为1的位”对应的位都设为1
- 返回更动后的bitset

bitset<bits>& bitset<bits>::operator &= (const bitset<bits>& bits)
- 对每个位逐一进行与运算
- 将*this中所有和“bits内数值为0的位”对应的位都设为0
- 返回更动后的bitset

bitset<bits>& bitset<bits>::operator <<= (size_t num)
- 将所有位向左移动num个位置
- 空出来的位设为false(0)
- 返回更动后的bitset

bitset<bits>& bitset<bits>::operator >>= (size_t num)
- 将所有位向右移动num个位置
- 空出来的位设为false(0)
- 返回更动后的bitset

4. 使用operator[]存取位

bitset<bits>::reference bitset<bits>::operator[] (size_t idx)
bool bitset<bits>::operator[] (size_t idx) const
- 都将返回位置idx上的位值
- 第一种形式针对non-const类型,使用了proxy型别
- 调用者须确保idx有效,否则导致未定义的行为

5. 产生新的bitset

bitset<bits> bitset<bits>::operator ~ () const
- 产生一个新的bitset并返回;以*this的位翻转值作为初值

bitset<bits> bitset<bits>::operator << (size_t num) const
- 产生一个新的bitset并返回;以*this的位向左移动num个位置作为初值

bitset<bits> bitset<bits>::operator >> (size_t num) const
- 产生一个新的bitset并返回;以*this的位向右移动num个位置作为初值

bitset<bits> bitset<bits>::operator & (const bitset<bits>& bits1, const bitset<bits>& bits2) 
- 对bits1和bits2按位进行与运算并返回结果
- 返回的结果中只有bits1和bits2中都为1的位置才被设为1

bitset<bits> bitset<bits>::operator | (const bitset<bits>& bits1, const bitset<bits>& bits2) 
- 对bits1和bits2按位进行或运算并返回结果
- 返回的结果中只有bits1或bits2中都为1的位置才被设为1

bitset<bits> bitset<bits>::operator ^ (const bitset<bits>& bits1, const bitset<bits>& bits2) 
- 对bits1和bits2按位进行异或运算并返回结果
- 返回的结果中只有bits1和bits2中位值相异的位置才被设为1

6. 型别转换

unsigned long bitset<bits>::to_ulong () const
- 返回bitset所有位所代表的整数
- 如果unsigned long不足以表示这个数,抛出overflow_error异常

string bitset<bits>::to_string () const
- 返回一个string,以字符串形式表示该bitset的二进制值
- 字符顺序按照bitset的索引高低排列

7. I/O操作

istream& operator >> (istream& strm, bitset<bits>& bits)
- 将一个包含‘0’和‘1’的字符序列转换为对应位,读入bits
- 读取行为一直进行下去,直到发生:
  读取结束, strm中出现end-of-file符号, 下一个字符既非'0'也非'1'
- 返回strm
- 若读入的位少于bits设置的位数量,前面不足的位填0

ostream& operator << (ostream& strm, bitset<bits>& bits)
- 将bits的二进制形式转换为字符串
- 使用to_string产生输出字符
- 返回strm

三、程序示例

bitset的使用示例

//example of bitset
#include <bitset>
#include <iostream> 
#include <string>
#include <limits>
using namespace std;

int main()
{
    enum color { red, yellow, green, blue, white, black, numColors};
    bitset<numColors> usedColors;
    cout << numColors << endl;

    usedColors.set(red);
    usedColors.set(blue);

    cout << "bitfield of used colors: " << usedColors << endl;
    cout << "number of used colors: " << usedColors.count() << endl;
    cout << "bitfield of unused colors: " << ~usedColors << endl;

    cout << "10000000 with 24 bits: " << bitset<24>(1e7) << endl;

    cout << "\"1000101011\" as number: "
        << bitset<100>(string("1000101011")).to_ulong() << endl;

    bitset<10> flags1(8);
    cout << "flags1" << flags1 << endl;
    bitset<10> flags2(string("110110011111"),1,5); //从第二个字符起,截取5个字符
    cout << "flags2" << flags2 << endl;
    cout << "flags2.size:" << flags2.size() << endl;

    if (flags2.any())
        cout << "flags2 has 1 existed!" << endl;
    if (flags2.none())
        cout << "flags2 only has 0" << endl;
    if (flags1 != flags2)
        cout << "flags1 != flags2" << endl;

    cout << "flags1 after set 1: " << flags1.set() << endl;
    cout << "flags1 after set idx=1 to 0: " << flags1.set(1,0) << endl;
    cout << "flags1 flip: " << flags1.flip() << endl;
    cout << "~flags1: " << ~flags1 << endl;
    cout << "flags1 as string: " << flags1.to_string() << endl;
	cout<<(flags1<<2)<<endl;
	cout<<flags1<<endl;
    return 0;
}

输出结果: 
STL特殊容器之bitset