【C++ 筆記】bitset 容器,C++ 二進位運算的絕佳利器
【C++ 筆記】bitset 容器,C++ 二進位運算的絕佳利器
很感謝你點進來這篇文章。
你好,我並不是什麼 C++、程式語言的專家,所以本文若有些錯誤麻煩請各位鞭大力一點,我極需各位的指正及指導!!本系列文章的性質主要以詼諧的口吻,一派輕鬆的態度自學程式語言,如果你喜歡,麻煩留言說聲文章讚讚吧!
什麼是 bitset?
std::bitset<N> 是 C++ STL(位於標頭檔 <bitset>)中,一個用來表示固定長度為 $N$ 位元(bits)的位元序列(bit sequence)的類別模版。
假設 $N = 16$ ,那就表示有 16 位元,數字 1 就會表示成 “0000000000000001”。
bitset 也是 C++ 當中的一種容器,這個容器能夠做到單獨、有效的去操作每一個位元,也能解決位元運算、實現二進位表示法的工具,這也是為什麼需要用到它的原因。
使用 bitset
bitset 在使用之前需要引入標頭檔 <bitset>,另外以下是其基本語法:
1 | bitset<n> name; |
其中 n 是固定的位元數,而 name 則為 bitset 容器的名稱。
初始化 bitset
可以透過建構子 () 對 bitset 進行初始化的動作,如下程式碼做的動作:
1 |
|
Output:
1 | 0000000000000101 |
由於給予的初始值是十進位的數字 5,所以理所當然會輸出 2 進位 16 bits 的 5。
初始值不一定是給予十進位數字,也可以是二進位字串:
1 |
|
Output:
1 | 0000000000000101 |
你也可以選擇不加上初始值,那預設就會是 16 個 0:
1 |
|
Output:
1 | 0000000000000000 |
最後是比較奇特的自訂字元初始化,可以指定哪個字元代表 1,哪一個代表 0:
1 |
|
Output:
1 | 0011101010101001 |
存取 bitset 的單一位元
使用 [] 運算子,裡面索引一樣是從 0 開始。
1 |
|
Output:
1 | 1 |
bitset 常用函數
設定、重置操作
set():設定位元為 1。
1 |
|
Output:
1 | 111011 |
reset():重置位元為 0。
1 |
|
Output:
1 | 位元重置:000000 |
flip():翻轉位元(0 變 1,1 變 0)。
1 |
|
Output:
1 | 011101 |
查詢操作
test():測試某位元是否為 1。
1 |
|
Output:
1 | 第一位是 1 嗎?No |
count():計算有多少個 1。
這蠻好用的,有些題目會考有多少個 1,直接用上這個就對了。
1 |
|
Output:
1 | 有多少個 1?1 |
size():回傳 bitset 的大小,這就不提供範例了。any():是否有任何位元為 1。
1 |
|
Output:
1 | 全都是1?Yes |
all():是否所有位元都為 1。
1 |
|
Output:
1 | 全都1?No |
none():是否所有位元都為 0。
1 |
|
Output:
1 | 全都0?No |
型態轉換操作
to_string():轉成字串。
1 |
|
Output:
1 | 100000 |
to_ulong():轉成 unsigned long。
1 |
|
Output:
1 | 32 |
to_ullong():轉成 unsigned long long。
1 |
|
Output:
1 | 32 |
支援的位元運算子
Bitset 支援以下這幾種位元運算子:
&:AND|:OR^:XOR~:NOT>>=:右移賦值運算子。<<=:左移賦值運算子。&=:AND 賦值運算子。|=:OR 賦值運算子。^=:XOR 賦值運算子。
範例:
1 |
|
Output:
1 | 10100000 |
也可以做比較運算:
1 |
|
Output:
1 | not equal |
為什麼要用 bitset?
首先是空間效率使用的問題,bitset 一個元素只占一個 bit 而已,而一個 char 是一個 byte,等於 8 個 bit,就可見他的使用效率,比什麼 bool 陣列來得更省記憶體。
再來是高效能的操作,因為在編譯時期(Runtime)就確定大小,能進行高效的位元儲存和操作。
最後就是因為他蠻好用的,不用自己手搓完整的位元運算出來。
習題練習
Uva 10019 - Funny Encryption Method
Uva Online Judge:https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=960
Zerojudge:https://zerojudge.tw/ShowProblem?problemid=e545
PDF Source:https://onlinejudge.org/external/100/10019.pdf
範例程式碼:
1 |
|
Uva 10931 - Parity
Uva Online Judge:https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=24&problem=1872
Zerojudge:https://zerojudge.tw/ShowProblem?problemid=a132
PDF Source:https://onlinejudge.org/external/109/10931.pdf
範例程式碼:
1 |
|
總結
std::bitset<N> 是 C++ STL 中用來表示固定長度 N 位元的容器,需要引入 <bitset> 標頭檔。它能有效地操作每一個位元,是處理位元運算和二進位表示的實用工具。
四種初始化方法:
- 十進位數字:
bitset<16> a(5)輸出0000000000000101 - 二進位字串:
bitset<16> a("101")輸出0000000000000101 - 預設值(全為 0):
bitset<16> a輸出0000000000000000 - 自訂字元:
bitset<16> a("ooxxxoxox", 16, 'o', 'x')可指定哪個字元代表 0 或 1
存取位元:
- 使用
[]運算子,索引從 0 開始,例如a[0]存取第一個位元。
設定與重置:
set():將位元設為 1(可指定位置或全部)reset():將位元設為 0(可指定位置或全部)flip():翻轉位元(0 變 1,1 變 0)
查詢操作:
test(pos):測試指定位元是否為 1count():計算有多少個 1any():檢查是否有任何位元為 1all():檢查是否所有位元都為 1none():檢查是否所有位元都為 0size():回傳 bitset 大小
型態轉換:
to_string():轉換為字串to_ulong():轉換為 unsigned longto_ullong():轉換為 unsigned long long
參考資料
C++ Bitset and its Application - GeeksforGeeks



