BitSet

BitSet

C++語言的一個類庫,用來方便地管理一系列的bit位而不用程序員自己來寫代碼。

bitset除了可以訪問指定下標的bit位以外,還可以把它們作為一個整數來進行某些統計。

bitset操作


c++

可以如下聲明一個該類型變數:
bitsetvarm (M)
其中varm為變數名。
N表示該類型在內存中占的位數,是二進位
M表示變數varm的初始值。

bitset聲明及操作

BitSet
BitSet
用整值類型表示位向量的問題在於:使用位操作符來設置複位和測試單獨的位層次比較低也比較複雜.
例如:用整值類型將第27 位設置為1, 我們這樣寫
quiz1 |= 1<<27;
而用bitset 來做我們可以寫
quizl[ 27 ] = 1;
quiz1.set( 27 );
要使用bitset 類我們必須包含相關的頭文件
聲明1:
bitset 有三種聲明方式。在預設定義中,我們只需簡單地指明位向量的長度。例如:
bitset< 32 > bitvec;
聲明了一個含有32 個位的bitset,對象位的順序從0 到31。預設情況下所有的位都被初始化為0 。
相關函數:
1. any():
為了測試bitset 對象是否含有被設置為1的位,我們可以使用any()操作
當bitset對象的一位或多個位被設置為1 時any()返回true
例如,對於bitvec ,如下測試
bool is_set = bitvec.any();
它的結果當然是false。
2. none():
相反,如果bitset 對象的所有位都被設置為0 ,則none()操作返回true
例如,對於bitvec 測試
bool is_not_set = bitvec.none();
結果為true
3. count():
count()操作返回被設置為1的位的個數.
int bits_set = bitvec.count();
4. set():
我們可以用set()操作或者下標操作符來設置某個單獨的位
例如,下面的for循環把下標為偶數的設置為1.
for ( int index = 0; index < 32; ++ index )
if ( index % 2 == 0 )
bitvec[ index ] = 1;
5. test():
類似地,測試某個單獨的位是否為1 也有兩種方式
test()操作。用位置做參數,返回true或false 例如:
if ( bitvec.test( 0 ))// 我們的bitvec[0] 可以工作了!
同樣地,我們也可以用下標操作符
cout << "bitvec: positions turned on:\n\t";
for ( int index = 0; index < 32; ++index )
if ( bitvec[ index ] )cout << index << " ";
cout << endl;
6. reset():
要將某個單獨的位設置為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 )
// 喔! 又錯了
7. flip():
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
因為 012 在c語言中表示八進位數字12即二進位數字“1010”
我們還可以傳遞一個代表0 和1 的集合的字元串參數來構造bitset 對象如下所示
// 與bitvec3 的初始化等價
string bitval( "1010" );
bitset< 32 > bitvec4( bitval );
bitvec4 和bitvec3 的第1 和3 位都被設置為1 而其他位保持為0
bitvec.set();

MATLAB函數


設置數的某一位二進位位為1. 《Simulink與信號處理

使用方法

C = bitset(A,bit)
將數A的第bit二進位位設為1.
C = bitset(A,bit,V) 《Simulink與信號處理》
將數A的第bit二進位位設為V,V必須為0或1.

應用舉例

例1: .
C = bitset(uint8(9),5) C = 25 將數字9(01001)的第5位設為1,C的二進位位11001 例2: C = bitset(uint8(9),1,0)
C = 8 將數字9的第1位設為0

相關函數

bitget, bitand, bitor, bitxor, bitcmp, bitshift

java 集合


BitSet 實際是由“二進位位”構成的一個Vector。如果希望高效率地保存大量“開-關”信息,就應使用
BitSet。它只有從尺寸的角度看才有意義;如果希望的高效率的訪問,那麼它的速度會比使用一些固有類型
的數組慢一些。
此外,BitSet 的最小長度是一個長整數(Long)的長度:64 位。這意味著假如我們準備保存比這更小的數
據,如8 位數據,那麼BitSet 就顯得浪費了。所以最好創建自己的類,用它容納自己的標誌位。
在一個普通的Vector 中,隨我們加入越來越多的元素,集合也會自我膨脹。在某種程度上,BitSet 也不例
外。也就是說,它有時會自行擴展,有時則不然。而且Java 的1.0 版本似乎在這方面做得最糟,它的
BitSet 表現十分差強人意(Java1.1 已改正了這個問題)。下面這個例子展示了BitSet 是如何運作的,同時
演示了1.0 版本的錯誤:
//: Bits.java
// Demonstration of BitSet
import java.util.*;
public class Bits {
public static void main(String[] args) {
Random rand = new Random();
// Take the LSB of nextInt():
byte bt = (byte)rand.nextInt();
BitSet bb = new BitSet();
for(int i = 7; i >=0; i--)
if(((1 << i) & bt) != 0)
bb.set(i);
else
bb.clear(i);
System.out.println("byte value: " + bt);
printBitSet(bb);
short st = (short)rand.nextInt();
BitSet bs = new BitSet();
for(int i = 15; i >=0; i--)
if(((1 << i) & st) != 0)
bs.set(i);
else
bs.clear(i);
System.out.println("short value: " + st);
printBitSet(bs);
int it = rand.nextInt();
BitSet bi = new BitSet();
for(int i = 31; i >=0; i--)
if(((1 << i) & it) != 0)
bi.set(i);
else
bi.clear(i);
System.out.println("int value: " + it);
printBitSet(bi);
// Test bitsets >= 64 bits:
BitSet b127 = new BitSet();
b127.set(127);
222
System.out.println("set bit 127: " + b127);
BitSet b255 = new BitSet(65);
b255.set(255);
System.out.println("set bit 255: " + b255);
BitSet b1023 = new BitSet(512);
// Without the following, an exception is thrown
// in the Java 1.0 implementation of BitSet:
// b1023.set(1023);
b1023.set(1024);
System.out.println("set bit 1023: " + b1023);
}
static void printBitSet(BitSet b) {
System.out.println("bits: " + b);
String bbits = new String();
for(int j = 0; j < b.size() ; j++)
bbits += (b.get(j) ? "1" : "0");
System.out.println("bit pattern: " + bbits);
}
} ///:~
隨機數字生成器用於創建一個隨機的byte、short 和int。每一個都會轉換成BitSet 內相應的位模型。此時
一切都很正常,因為BitSet 是64 位的,所以它們都不會造成最終尺寸的增大。但在Java 1.0 中,一旦
BitSet 大於64 位,就會出現一些令人迷惑不解的行為。假如我們設置一個只比BitSet 當前分配存儲空間大
出1 的一個位,它能夠正常地擴展。但一旦試圖在更高的位置設置位,同時不先接觸邊界,就會得到一個惱
人的違例。這正是由於BitSet 在Java 1.0 里不能正確擴展造成的。本例創建了一個512 位的BitSet。構建
器分配的存儲空間是位數的兩倍。所以假如設置位1024 或更高的位,同時沒有先設置位1023,就會在Java
1.0 里得到一個違例。但幸運的是,這個問題已在Java 1.1 得到了改正。所以如果是為Java 1.0 寫代碼,
請盡量避免使用BitSet。
《摘自Think in Java》