17.2 bitset类型
包含头文件 bitset
17.2.1 定义和初始化bitset
//类模板,32表示的是位数,左边是高位,右边是低位,而且低位是1,还是unsigned的
bitset<32>bitvec(1U);
//bitvec1比初始值小;初始值的高位被抛弃
//只有13位 ,f表示1111,e1110 ,e1110,b1011
//1011 1110 1110 1111
//只能表示为1111011101111 。高位101被截断了
bitset<13>bitvecl(0xbeef);
//bieset2的位数超过了初始化的位数,最高位补零
// 0000 1011 1110 1110 1111
bitset<20>bitvec2(0xbeef);
//在64位机器中,long long 0ULL是64个 0比特 ~取反符 ~0ULL是64个1
bitset<128>bitvec3(~0ULL); //0~63位数为;高位63~127位为0
}
从一个string 初始化 bitset
//用字符串表示数字,字符串下标最小的字符对应高位
//高位2,3位为1 1,低位0,1 为0 0
bitset<32>bitvec4("1100");
//string包含的字符数比bitset少,则bitset的高位被置为0
//字符串从左边零位开始到[5]这里开始拷贝
string str("11111110000000011001101");
//从str[5]开始的四个二进制位1100
bitset<32>bitvec5(str, 5, 4);
//1101
bitset<32>bitvec6(str, str.size() - 4);
17.22.1节练习
//低位0010 0000 ,其他位数为0
bitset<64>bitveC(32);
cout << bitveC << endl;
//0000 0000 0000 0000 0000 0000 0101 0101
bitset<32>bc(1010101);
cout << bc << endl;
//假设输入是1010 ,结果应该是0000 1010
string bstr; cin >> bstr; bitset<8>bv(bstr);
cout << bv << endl;
17.2.2 bitset操作
//32位,低位为,剩余位为0
bitset<32>bitvec(1U);
//true,有1位置位
bool is_set = bitvec.any();
//有1了,所以为false
bool is_not_set = bitvec.none();
//只有一个位置为1,其他没有,所以为false
bool all_set = bitvec.all();
//返回1
size_t onBits = bitvec.count();
//返回32
size_t sz = bitvec.size();
//翻转bitvec中的所有位
bitvec.flip();
cout << bitvec << endl;
//将所有复位 全部为0
bitvec.reset();
cout << bitvec << endl;
//将所有位置位 就是全部为1
bitvec.set();
cout << bitvec << endl;
//翻转第一位
bitvec.flip(0);
cout << bitvec << endl;
//置位最后一位
bitvec.set(bitvec.size() - 1);
cout << bitvec << endl;
//复位第一位
bitvec.set(0, 0);
cout << bitvec << endl;
//复位第i位 i表示位置从低位开始
int i = 1;
bitvec.set(i);
cout << bitvec << endl;
//返回false,因为最低位是复位就是0
bool c =bitvec.test(0);
cout << c << endl;
bitvec[0] = 0;//第一位复位
bitvec[31] = bitvec[0];//最高位和最低位一样是0
cout << bitvec << endl;
//翻转第一位置为1
bitvec[0].flip();
cout << bitvec << endl;
//~等价操作
~bitvec[0];
//讲最低位值转换为bool类型
bool b = bitvec[0];
提取bitset的值
//在64位机器中,long long 0ULL是64个 0比特 ~取反符 ~0ULL是64个1
bitset<64>bitvec3(10011); //0~63位数为;高位63~127位为0
unsigned long ulong = bitvec3.to_ullong();
cout << "ulong = " << ulong << endl;
bitset的io运算符
```cpp
bitset<16>bits;
//存到临时的string中,遇到不是0 1或者输入错误 或者文件尾,读取过程结束
//临时对象初始化bitset
//读取小于bits,高位为0
cin >> bits;
cout << "bits" << bits << endl;
**使用bitset**
```cpp
bool status;
unsigned long quizA = 0; //
quizA |= 1UL << 27;
cout << quizA << endl;
status = quizA & (1UL << 27);
cout << status << endl;
quizA &= ~(1UL << 27);
cout << quizA << endl;
bitset<30>quizB;
quizB.set(27);
status = quizB[27];
quizB.reset(27);
cout << quizB << endl;
练习17.11
bitset<32>bitset1;
bitset1.set(1);
bitset1.set(2);
bitset1.set(3);
bitset1.set(5);
bitset1.set(8);
bitset1.set(13);
bitset1.set(21);
cout << bitset1 << endl;
bitset<32>bitset2;
cout << bitset2 << endl;
练习17.12 解答链接https://zhuanlan.zhihu.com/p/361437127
如果使用整数保存测验解答,那么对于10个问题的测验,只需一个短整型对象即可。如果改为100道题,则需要4个32位整数或是2个64位整数。而且修改的并不仅仅是数据结构,对所有整型数进行操作来修改解答和评分的代码都要相应进行修改,工作量很大。
采用bitset则有很明显的优势,当题目数改变时,我们只需改变bitset的规模,而操作bitset来完成改答案、评分的代码则只需要进行很小的修改。
最佳的方式是定义一个类模板,它有一个模板参数表示题目数,有一个bitset成员保存解答,然后定义一些成员函数来完成改答案、评分等操作。当题目数发生变化,我们只需实例化一个新版本即可,其它代码均无序改动。
练习17.13 14
template<size_t N>
class test
{
public:
test():b(){}
void set_result(size_t pos, bool v) { b.set(pos, v); }
bitset<N>get_result()const { return b; }
size_t score(const bitset<N>&);
private:
bitset<N>b;
};
template<size_t N>
size_t test<N>::score(const bitset<N>& r)
{
size_t ret = 0;
for (auto i = 0; i < N; ++i)
{
if (b[i] == r[i])
{
ret++;
}
}
return ret;
}
int main()
{
test<16>t1;
t1.set_result(5, 1);
t1.set_result(13, 1);
auto r = t1.get_result();
cout << r << endl;
bitset<16>t2;
cout << "t2 score" << t1.score(t2) << endl;
}