首页 > 代码库 > BitSet的使用
BitSet的使用
有些程序需要处理二进制有序集,标准库提供了bitset 类型,事实上,bitset 是一个二进制容器,容器中每一个元素都是一位二进制码,或为 0,或为 1。bitset除了可以访问指定下标的bit位以外,还可以把它们作为一个整数来进行某些统计。
1、定义与初始化
使用:
#include <bitset>
using std::bitset;
在定义 bitset 时,要明确 bitset 有多少位,这个位数是整型常量:
bitset<n> b; //b 有 n 位,每位都是 0
bitset<n> b(u); //b 是 unsigned long 型 u 的一个副本
bitset<n> b(s); //b 是 string 对象 s 中含有的位串的副本,这个s 必须是位串,也就是二进制码串
bitset<n> b(s, pos, n); //b 是 s 中 从位置 pos 开始的 n 个位的副本。
2、bitset操作
用整值类型表示位向量的问题在于使用位操作符来设置复位和测试单独的位层次比较低也比较复杂.
例如用整值类型将第27 位设置为1, 我们这样写
quiz1 |= 1<<27;
而用bitset 来做我们可以写
quizl[ 27 ] = 1;
或
quiz1.set( 27 );
要使用bitset 类我们必须包含相关的头文件
#include <bitset>
bitset 有三种声明方式在缺省定义中我们只需简单地指明位向量的长度例如
bitset< 32 > bitvec;声明了一个含有32 个位的bitset 对象位的顺序从0 到31 缺省情况下所有的位都被
初始化为0 为了测试bitset 对象是否含有被设置为1 的位我们可以使用any()操作当bitset
对象的一位或多个位被设置为1 时any()返回true 对于bitvec .如下测试
bool is_set = bitvec.any();
它的结果当然是false 相反如果bitset 对象的所有位都被设置为0 ,则none()操作返回
true 对于bitvec 测试
bool is_not_set = bitvec.none();
结果为true count()操作返回被设置为1 的位的个数.
int bits_set = bitvec.count();
我们可以用set()操作或者下标操作符来设置某个单独的位例如下面的for 循环把偶数位设置为1.
for ( int index = 0; index < 32; ++ index )
if ( index % 2 == 0 )
bitvec[ index ] = 1;类似地测试某个单独的位是否为1 也有两种方式test()操作用位置做参数返回true
或false 例如
if ( bitvec.test( 0 ))
// 我们的bitve[0] 可以工作了!
同样地我们也可以用下标操作符
cout << "bitvec: positions turned on:\n\t";
for ( int index = 0; index < 32; ++index )
if ( bitvec[ index ] )
cout << index << " ";
cout << endl;
要将某个单独的位设置为0 ,我们可以用reset()或下标操作符下列两个操作都将bitvec的第一位设为0.
// 两者等价都把第一位设置为0
bitvec.reset( 0 );
bitvec[ 0 ] = 0;
我们也可以用set()和reset()操作将整个bitset 对象的所有位设为1 或0 ,只要调用相应的操作而不必传递位置参数我们就可以做到这一点.例如
// 把所有的位设置为0
bitvec.reset();
if ( bitvec.none() != true )
// 喔! 错了
// 把所有的位设置为1if ( bitvec.any() != true )
// 喔! 又错了
flip()操作翻转整个bitset 对象或一个独立的位
bitvec.flip( 0 ); // 翻转第一位
bitvec[0].flip(); // 也是翻转第一位
bitvec.flip(); // 翻转所有的位的值
还有两种方法可以构造bitset 对象它们都提供了将某位初始化为1 的方式:一种方法是为构造函数显式地提供一个无符号参数bitset 对象的前N 位被初始化为参数的相应位值,例如
bitset< 32 > bitvec2( 0xffff );
将bitvec2 的低16 位设为1
下面的bitvec3 的定义
bitset< 32 > bitvec3( 012 );
将第1 和3 位的值设置为1 假设位置从0 开0
我们还可以传递一个代表0 和1 的集合的字符串参数来构造bitset 对象如下所示
// 与bitvec3 的初始化等价
string bitval( "1010" );
bitset< 32 > bitvec4( bitval );
bitvec4 和bitvec3 的第1 和3 位都被设置为1 而其他位保持为0
bitvec.set();
3、相关函数
b.any() //b 中是否存在置为 1 的二进制位?
b.none() // 和b.any() 效果一样
b.count() //b 中不存在置为 1 的二进制位吗?
b.size() //b 中置为 1 的二进制位的个数
b[pos] //访问 b 中在 pos 处二进制位
b.test(pos) //b 中在 pos 处的二进制位置为 1
b.set() // 把 b 中所有二进制位都置为 1
b.set(pos) //把 b 中在 pos 处的二进制位置为 1
b.reset() //把 b 中所有二进制位都置为 0
b.reset(pos) //把 b 中在 pos 处的二进制位置为 0
b.flip() //把 b 中所有二进制位逐位取反
b.flip(pos) //把 b 中在 pos 处的二进制位取反
b.to_ulong() //用 b 中同样的二进制位返回一个 unsigned long 值
os << b //把 b 中的位集输出到 os 流
实验代码及运行结果:
#include "stdafx.h" #include <iostream> #include <bitset> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { //bitset的所有操作: //any();none();test();bit[];set();reset();to_string();to_ulong(); //count();flip();分别用十进制,八进制,十六进制,字符串赋值。 bitset<32> bitvec(8);//0~31,将数字8转为2进制形式存储。0001000000.... bool flag = bitvec.any();//判断是否存在某位或者多位为1,有则返回true bool flag1 = bitvec.none();//判断是否所有的位都是0,是则返回true bool flag2 = bitvec.test(3);//测试第4位是否为1,是则返回true<< cout<<"bitvec的值为:"<<bitvec<<endl; cout<<"第4位为:"<<bitvec[3]<<endl;//输出第4位的值 bitvec.reset(3);//将第4位设置为0,或者bitvec[3] = 0 cout<<"bitvec.reset(3)之后第4位为:"<<bitvec[3]<<endl;//输出第4位的值 bitvec.reset();//将所有位设置为0 cout<<"bitvec.reset()之后bitvec的值为:"<<bitvec.to_string()<<endl; bitvec.set();//将所有位设置为1 cout<<"bitvec.set()之后bitvec.to_string()的值为:"<<bitvec.to_string()<<endl; cout<<"bitvec的值为:"<<bitvec<<endl; cout<<"bitvec.to_ulong()的值为:"<<bitvec.to_ulong()<<endl; cout<<"bitvec中1的个数为:"<<bitvec.count()<<endl; bitvec = 8; cout<<"bitvec = 8之后bitvec的值为:"<<bitvec.to_string()<<endl; bitvec.flip();//将所有的位翻转 cout<<"bitvec.flip()之后bitvec的值为:"<<bitvec.to_string()<<endl; bitvec.flip(0);//翻转第一位 cout<<"bitvec.flip(0)之后bitvec的值为:"<<bitvec.to_string()<<endl; bitvec = 0xffff;//设置低16位为1 cout<<"bitvec = 0xffff之后bitvec的值为:"<<bitvec.to_string()<<endl; bitvec = 012;//用八进制值012设置bitvec,数字前加0表示为8进制!!! cout<<"bitvec = 012之后bitvec的值为:"<<bitvec.to_string()<<endl; string bit = "1011"; bitset<32> bitvec1(bit);//用字符串对象初始化bitset<32>对象 cout<<"bitvec1的值为:"<<bitvec1.to_string()<<endl; string bit1 = "1111110101100011010101"; bitset<32> bitvec2(bit1,6);//用从第6位开始到字符串结束这一部分初始化bitvec2 cout<<"bitvec2的值为:"<<bitvec2.to_string()<<endl; bitset<32> bitvec3(bit1,6,4);//用从第6位开始,长度为4这一部分初始化bitvec3; cout<<"bitvec3的值为:"<<bitvec3.to_string()<<endl; getchar(); return 0; }
BitSet的使用