重點
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 節將介紹這些操作符