重点
bitset是二进制位的有序集,里面的元素是0和1
没有定义的时候,bitset< n >b,b里面的元素默认初始化为0,n 个0
使用标准库bitset类型前要先声明 #include< bitset >
在定义bitset时,要明确bitset含有多少位,需在尖括号内给出长度值。bitset< 32 > bitvec; bitvec对象含有32位,以0(低阶位)开始,31结束;
bitset初始化给出的长度值必须是常量表达式,必须是定义为整型字面值常量或是已经用常量值初始化的整型的const对象
不管是unsigned 值还是string值初始化bitset对象,都是从右边向左边开始赋值,即从bitset的低阶位向高阶赋值,而且bitset低阶位下标最小,也就是说下标从右往左是越来越小的,这个不要搞错!!!(记住!!!)
当用unsigned long 值作为bitset 对象的初始值时,该值将转化为二进制的位模式
当用string对象初始化bitset对象时,string对象直接表示为位模式
当用string对象初始化时,需要注意:
================================================================================================
一、bitste对象的定义和初始化
1、bitset 对象的简介
- 有些程序要处理二进制位的有序集,每个位可能包含0(关)值或1(开)值。
位用来保存一组项或条件的yes/no信息(标志)的简洁方法。
使用标准库bitset类型前要先声明 #include< bitset >
2、bitset对象的定义和初始化
类似于vector ,bitset类也是一种类模板,而与vector不同的是bitset类型对象的区别仅在其长度而不在其类型。
在定义bitset时,要明确bitset含有多少位,需在尖括号内给出长度值。bitset< 32 > bitvec; bitvec对象含有32位,以0开始,31结束,0是低阶,31是高阶
- bitset所谓的高阶位和低阶位
以0xffff为例,在机器内的存储方式为:
00000000000000001111111111111111,从高阶-->低阶。
(我不确定是存储方式是从低到高还是高阶到低阶,如果是低阶到高阶,那么把数字1放到前面来)
给出的长度值必须是常量表达式,必须是定义为整型字面值常量或是已经用常量值初始化的整型的const对象;
和vector元素一样,bitset中的位是没有命名的,只能用位置来访问,这里是从0—31。
以0位开始的位串是低阶位,以31位结束的位串是高阶位
几种初始化方式
- bitset< n >b;//n表示位数,每位都为0
- bitset< n >b(u);//b是unsigned long型u 的一个副本
- bitset< n >b(s);//b是string对象s中含有的位串的副本
bitset< n >b(s , pos, n);//b是s中从位置pos开始的n个位的副本
bitset< n >b(s , pos);//省略第三个参数表示的是从开始位置pos一直到string末尾的所有字符(这个要和上面那个区分开来)
2、用unsigned 值初始化bitset 对象
当用unsigned long 值作为bitset 对象的初始值时,该值将转化为二进制的位模式。而bitset 对象中的位集作为这种位模式的副本。
从右边向左边开始赋值,即从低阶位向高阶。
如果bitset 类型长度大于unsigned long 值的二进制位数,则其余的高阶位置为0;
如果bitset 类型长度小于unsigned long 值的二进制位数,则只使用unsigned 值中的低阶位,超过bitset 类型长度的高阶位将被丢弃。
问题:在bitset 对象中,位数是怎么排的,高阶和低阶是怎么样的??
在32位的unsigned long 的机器上,十六进制值0xffff表示为
//例子,在32位的unsigned long 的机器上,十六进制值0xffff表示为二进制位就是16个1 和16个0 (每个0xf可以表示为1111)。用0xffff初始化bitset对象。
int main()
{
bitset<16> bitvec1(0xffff);
//bitset位数少于unsigned long的位数,所以,bitvec1的初始值高阶位被丢弃。bievec1 0---15设置为1
bitset<32> bitvec2(0xffff);
//bievec2 0---15设置为1 ;16---31设置为0
bitset<128> bitvec3(0xffff);
//bitset位数大于unsigned long的位数,所以,bitvec3的初始值高阶位被置为0。bievec1 32---127初始化为0
return 0;}
3、用string对象初始化bitset 对象
当用string对象初始化bitset对象时,string对象直接表示为位模式。
从string对象读入位集的顺序是从右到左;
string对象和bitset对象之间是反向转化的:string对象的最右边字符(下标最大的)用来初始化bitset对象的低阶位(下标为0的)!!!!但是他们下标最大的那个字符都是在最右边的,这个不要搞错
不一定要把string对象都作为bitset对象的初始值,可以只用某个子串作为初始值。
string strval("1100");
bitset<32> bitvec4(strval);
//bitvec4的位模式中第2和第3的位置为1,其余位置为0.
string str("1111111000000011001101");
bitset<32> bitvec5(str,5,4);//从str[5]开始的4个位,1100,bitvec5从3到0的二进制位置为1100,其余位置为0。
bitset <32> bitvec6(str,str.size()-4);
//省略第三个参数意味着取从开始位置一直到string末尾的所有字符。
//本例中,取出str末尾的四位来对bitvec6的低四位进行初始化。
//针对用string对bitset对象进行的初始化,我们首先把要拿来赋值的那段子串取出来(按照正常的顺序),再按他原本的顺序放到bitset对象里面,高阶位用0补。
4、输出bitset里面的元素
bitset<16> bitvec1(0xfffa);
bitset<32> bitvec2(0xfffa);
cout<<"bitvec1:"<<bitvec1<<endl;
cout<<"bitvec2:"<<bitvec2<<endl;
//输出:
//bitvec1:1111111111111010
//bitvec2:00000000000000001111111111111010
输出并不是期待的顺序,而是相反的。这里还要说的是,bitset实现的<<操作符输出时,将会从bitset的高阶–>低阶输出(更自然)。
因此若用for循环从0开始输出就会是实际存储的顺序了。因为for循环从小的下标开始输出,也就是低阶开始输出。
#include <iostream>
#include<cstring> //使用下面的那些
#include<bitset>
using namespace std;
int main(){
bitset<16> bitvec1(0xfffa);
bitset<32> bitvec2(0xfffa);
cout<<"bitvec1:"<<bitvec1<<endl; //输出的是bitvec1:1111111111111010
cout<<"bitvec2:"<<bitvec2<<endl;
//输出的是bitvec2:00000000000000001111111111111010
cout<<"bitvec1:";
for(size_t bs1 = 0;bs1!=bitvec1.size();bs1++)
{
cout<<bitvec1[bs1];
}
cout<<endl;
//输出的是bitvec1:0101111111111111
cout<<"bitvec2:";
for(size_t bs1 = 0;bs1!=bitvec2.size();bs1++)
{
cout<<bitvec2[bs1];
}
cout<<endl;
//输出的是bitvec2:01011111111111110000000000000000
return 0;
}
//输出的结果:
//没用for循环,从高阶到低阶输出
bitvec1:1111111111111010
bitvec2:00000000000000001111111111111010
//用for循环,从低阶到高阶输出
bitvec1:0101111111111111
bitvec2:01011111111111110000000000000000
二、bitste对象上的操作
1、测试整个bitset对象
- 如果bitset对象中有一个或几个二进制位置为1,则 any操作返回true;
- 如果要知道bitset 对象中1的个数,可以使用count操作,该操作返回置为1的二进制的个数;
-
2、访问bitset对象中的位
- 可以用下标操作符来读写某个索引位置的二进制位;
for(int index=0;index!=32;index+=2)
{bitbec[index]=1;}
- 也可以使用set、test、和reset 操作来充值二进制位的值
3、对整个bitset 对象进行设置
- set 和reset 分别用来对整个bitset 对象的所有二进制位全置为1和0.
- flip 操作可以对bitset 对象的所有位或个别位取反
bitvec.reset();//所有比特全设为0
bitvec.set();//所有比特全设为1
bitvec.flip(0);//第一个比特位取反
bitvec[0].flip();
bitvec.flip();//全部比特位取反
4、获取bitset 对象的值
17.1节后面再讨论
5、输出二进制位
//可以用输出操作符输出bitset对象中的位模式
bitset<32>bitvec2(0xffff);// 从0到15设为1,从16到31设为0
cout<<“bitvec2:”<<bitvec2<<endl;
//输出结果
//bitvec2:00000000000000001111111111111111
//有没有发现输出来的顺序是反的,就是从高阶位开始输出
6、使用位操作符
5.3 节将介绍这些操作符