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;
}
输出结果: