1. 程式人生 > >C++ bitset的使用簡介

C++ bitset的使用簡介

bitset簡介

template<size_t _Nb>  
class bitset: private _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)>  
{  
}

bitset是拿unsigned long實現的,如果std::bitset<_Nb> b;_Nb的大小小於unsigned long所佔的bit位數,就是直接用一個unsigned long型別的資料儲存bitset的結果(特化的類模版,一些函式會有優化)。如果是大於一個unsigned long型別資料所佔的bit位數,那麼就建一個unsigned long

型別的陣列來儲存。

建構函式

bitset();  
bitset(unsigned long val);  
explicit bitset(const std::basic_string<...>& s, size_t position = 0);//拿std::string直接作為s的引數就可以了  
bitset(const std::basic_string<...>& s, size_t position, size_t n);  
bitset(const std::basic_string<...>& s, size_t position, size_t n, char zero, char one = '1'
); //如果編譯器支援C++11 constexpr bitset(unsigned long long val); explicit bitset(const char* str, size_t n=XX::npos, char zero = '0', char one = '1');

建構函式示例程式碼

#include <iostream>
#include <bitset>
#include <string>

int main()
{
  //呼叫bitset();
  std::bitset<8> a;
  std
::cout << a << std::endl;//輸出 00000000 //呼叫bitset(unsigned long val); std::bitset<8> b(15); std::cout << b << std::endl;//輸出 00001111 //呼叫bitset(s, size_t position=0); std::string str("1010"); std::bitset<8> c1(str); std::cout << c1 << std::endl;//輸出 0000拼接上1010 std::bitset<8> c2(str,1); std::cout << c2 << std::endl;//輸出 00000拼接上010 //呼叫bitset(s, size_t position=0); //std::string str("1010"); std::bitset<8> d(str,0,3); std::cout << d << std::endl;//輸出 00000拼接上101 //呼叫bitset(s, size_t position, size_t n, char zero, char one = '1' ); std::string stre1("abab"); std::bitset<8> e1(stre1,0,2,'b','a');//a字元被認為是1,b被認為是0 std::cout << e1 << std::endl;//輸出 000000拼接上10 std::string stre2("7878"); std::bitset<8> e2(stre2,0,2,'8','7');//'7'-->'1','8'-->'0' std::cout << e2 << std::endl;//輸出 000000拼接上10 #if __cplusplus >= 201103L //下面說的很重要,沒注意引數型別,被坑了好久 //呼叫explicit bitset(const char* str, size_t n = XX::npos, char zero = '0', char one = '1'); //注意第一個引數是char*型別,如果是std::string 型別就會呼叫引數為const std::basic_string<...>& s的建構函式 std::bitset<8> f1("1010"); std::cout << f1 << std::endl;//輸出 00001010 std::bitset<8> f2("abab",3,'b','a'); std::cout << f2 << std::endl;//輸出 00000101 //呼叫constexpr bitset(unsigned long long val); std::bitset<45> g(8589934592);//8589934592等於2^33 std::cout << g << std::endl;//輸出 000000000001000000000000000000000000000000000 #endif return 0; }

操作符

bitset過載的操作符號包括

&=,|=,^=  
&, |,~  
左移右移:<<=,>>=,<<,>>  
[]  
輸入輸出:>>,<<  
==,!= 

這裡的操作符號和我們所已有的知識是差不多一樣的。其中要說明的一點是bitset的所有二元操作符所操作的兩個bitset型別的數一定要擁有相同的位長度,例如01&=0算是錯誤的操作。這裡還有必要說明的一點是輸入資料的>>操作符,如果輸入的串包含非0或者1的字元,那麼結果直接出錯,如果輸入的資料長度超過定義的bitset型別的長度,那麼多餘的字元會留在緩衝區(這裡如果有說錯請指正)作為下一次輸入,具體見程式碼。

#include <iostream>
#include <bitset>

int main()
{
    std::bitset<8> a("11110000");
    std::bitset<8> b("00001111");
    std::bitset<8> c;

    std::cout << (a&b) << std::endl; //00000000
    std::cout << (a|b) << std::endl; //11111111
    std::cout << (~a) << std::endl;  //00001111
    std::cout << (a<<2) << std::endl;//11000000
    std::cout << (a>>2) << std::endl;//00111100

    //每一步計算完之後a與b各自的結果
    a |= b; //a(11111111),b(00001111)
    a <<= 4;//a(11110000),b(00001111)
    a &= b; //a(00000000),b(00001111)
    a ^= b; //a(00001111),b(00001111)
    a >>= 2;//a(00000011),b(00001111)

    std::cout << a << std::endl;
    std::cout << b << std::endl;

    //此時a(00000011)
    if(a[0]){//這裡的a[0]返回的是bool型別的值
        a[0] = 0;//這裡的a[0]返回的是a[0]的引用,類比陣列吧
        std::cout << a[0] << std::endl;
    }

    //輸入00001111 -->輸出8 4 00001111
    //輸入000011111111 -->輸出8 4 00001111和8 4 00001111
    while(std::cin >> c){
        std::cout << c.size() << " " << c.count() << std::endl;
        std::cout << c << std::endl;
    }


    return 0;
}

set型別的函式

bitset<_Nb>& set();//全部設定為1
bitset<_Nb>& set(size_t __position, bool __val = true);//將__position位設定為__val
bitset<_Nb>& reset();//全部設定為0
bitset<_Nb>& reset(size_t __position);//__position為設定為0
bitset<_Nb>& flip();//取反操作
bitset<_Nb>& flip(size_t __position);//__position位取反

//to_string()函式還有一些輔助string的函式就不提了
std::basic_string<...> to_string();//轉換為01的字串
std::basic_string<...> to_string(char zero, char one = '1');//轉換為字串,用zero代替0,用one代替1

set型別函式的示例程式碼

#include <iostream>
#include <string>
#include <bitset>

int main()
{
    std::bitset<8> a;
    std::cout<< a << std::endl;//00000000
    a.set();
    std::cout<< a << std::endl;//11111111

    a.set(3,0);
    std::cout<< a << std::endl;//11110111

    a.reset();
    std::cout<< a << std::endl;//00000000

    a.set();
    a.reset(3);//效果等同於a.set(3,0);
    std::cout<< a << std::endl;//11110111


    a.flip();
    std::cout<< a << std::endl;//00001000

    a.flip(3);
    std::cout<< a << std::endl;//00000000

    std::string str(a.to_string());
    std::cout << str << std::endl;//00000000

    std::string str1(a.to_string('a','b'));
    std::cout << str1 << std::endl;//aaaaaaaa

    return 0;
}

get型別的函式

unsigned long to_ulong();//返回unsigned long型別 
unsigned long long to_ullong();//C++11的函式
size_t count();//計算1的個數
constexpr size_t size();//計算儲存了多少個bit位
bool test(size_t position);//和a[position]效果類似,注意返回值是bool

bool all();//所有都是1,返回true
bool any();//只要存在1,就返回true
bool none();//都是0,返回true

get型別的函式的示例程式碼

#include <iostream>
#include <bitset>

int main()
{
    std::bitset<8> a("01111111");
    std::bitset<45> b(8589934592);//2^33=8589934592

    std::cout << a.to_ulong() << std::endl; 

#if __cplusplus >= 201103L
    std::cout << b << std::endl;
    std::cout << b.to_ullong() << std::endl; 
#endif

    std::cout << a.count() << std::endl;//計算a中1的個數
    std::cout << a.size() << std::endl; //a中儲存了多少個bit位

    std::cout << std::boolalpha; 
    std::cout << a.test(7) << std::endl;//false
    std::cout << a.all() << std::endl;//false
    std::cout << a.any() << std::endl;//true
    std::cout << a.none() << std::endl;//false

    return 0;
}

擴充套件自SGI版本的函式

SGI版本擴充套件了好多bitset函式,不過由於沒有具體去看,而且也是擴充套件的,所以在此就不提了,有興趣的可以去看看bitset的實現原始碼,相對還是比較簡單的!