位圖,就是用每一個位元位來表示某種狀態,來判斷資料存在與否,
如:

位圖的優點: 節省空間,效率高
位圖的缺點: 只能處理整形
1.實作bitset
類模型:
class BitSet
{
public:
BitSet(size_t n = 31) //n為有多少位元位數
:_v((n >> 5) + 1) //+1是為了避免位元位數小于32時,無法開辟出空間
,_bitCount(n)
{}
private:
vector<int> _v;//底層存盤使用的是vector
size_t _bitCount;//位元位的位數
};
1.1 設定位元位
1 << bitpos是將該bitpos位置置為1,則進行或操作即可將位圖中置為1
void Set(size_t pos, bool val = true)//將pos位元位置為1
{
if (pos >= _bitCount)//pos位置應該小于位元位數,否則超出了范圍
{
cout << "out_of_range" << endl;
return;
}
if (val)//默認情況下,Set是將pos位置置為1
{
size_t index = (pos >> 5);//在第多少個int里面
size_t bitpos = pos % 32;//在該int中的位元位位置
_v[index] |= (1 << bitpos);
}
else//val = false時,呼叫Reset
ReSet(pos);
}
1.2 重置位元位
void ReSet(size_t pos)//將pos位置為0
{
if (pos >= _bitCount)//pos位置應該小于位元位數,否則超出了范圍
{
cout << "out_of_range" << endl;
return;
}
size_t index = (pos >> 5);//在第多少個整形里面
size_t bitpos = pos % 32;//將該位置置為0
_v[index] &= ~(1 << bitpos);//只將一個位置置為0,其余不變,則要將原資料取反,再與即可
}
1.3 檢測位元位
bool Test(size_t pos)
{
if (pos >= _bitCount)//pos位置應該小于位元位數,否則超出了范圍
{
cout << "out_of_range" << endl;
return false;
}
size_t index = (pos >> 5);//在第多少個整形里面
size_t bitpos = pos % 32;//位置
return _v[index] & (1 << bitpos);
}
完整代碼:
class BitSet
{
public:
BitSet(size_t n = 10)//n為位元位數
:_v((n >> 5) + 1)
,_bitCount(n)
{}
void Set(size_t pos, bool val = true)//將pos位元位置為1
{
if (pos >= _bitCount)
{
cout << "out_of_range" << endl;
return;
}
if (val)
{
size_t index = (pos >> 5);//在第多少個整形里面
size_t bitpos = pos % 32;//將該位置置為1
_v[index] |= (1 << bitpos);
}
else
ReSet(pos);
}
void ReSet(size_t pos)
{
if (pos >= _bitCount)
{
cout << "out_of_range" << endl;
return;
}
size_t index = (pos >> 5);//在第多少個整形里面
size_t bitpos = pos % 32;//將該位置置為0
_v[index] &= ~(1 << bitpos);
}
bool Test(size_t pos)
{
if (pos >= _bitCount)
{
cout << "out_of_range" << endl;
return false;
}
size_t index = (pos >> 5);//在第多少個整形里面
size_t bitpos = pos % 32;//位置
return _v[index] & (1 << bitpos);
}
private:
vector<int> _v;
size_t _bitCount;
};
測驗代碼:
int main()
{
BitSet bt(100);//100個位元位
bt.Set(10);//第10個位元位置為1
bt.Set(98);//第98個位元位置為1
bt.Set(12);//第12個位元位置為1
cout << bt.Test(10) << endl;//查看第10個位元位是否為1
bt.ReSet(12);//第12個位元位置為1
cout << bt.Test(12) << endl;//查看第12個位元位是否為0
bt.Set(98, 0);//第98個位元位置為0
cout << bt.Test(98) << endl;//查看第98個位元位是否為0
return 0;
}

2.C++庫函式中bitset
2.1 構造
- 值構造:構造時,可采用整數值構造,此時按照資料的二進制位元位,對bitset中對應的位元位置1;
代碼:
int main()
{
bitset<15> bt(10);
// 1010
cout << bt << endl;
return 0;
}
結果:

注意:當不足bitset位數時,高位補0,超出時,資料截斷,

- 字串構造:和值構造同理,當不足bitset位數時,高位補0,超出時,資料截斷,右邊為低位,左邊為高位,
例:

2.2 operator[]
函式原型:
bool operator[] (size_t pos) const; //const物件,回傳bool值,表示該位是否存在
reference operator[] (size_t pos); //回傳值,并且可對該值操作
注意:若pos 不要大于 位圖的位數,
例:
int main()
{
bitset<15> bt(string("010101"));
cout << bt << endl;
cout << bt[0] << endl;
return 0;
}
2.3 count
函式原型:
size_t count() const noexcept;
回傳值:回傳位圖中1的個數
例:

2.4 size
函式原型:
constexpr size_t size() noexcept;
回傳值:回傳位圖的位數
例:

2.5 test
函式原型:
bool test (size_t pos) const;
回傳值:回傳pos位置,資料是否存在
例:

2.6 any
函式原型:
bool any() const noexcept;
回傳值:若位圖中有1的個數大于等于1,則回傳真,1的個數為0,回傳假
例:

2.7 none
函式原型:
bool none() const noexcept;
回傳值:若位圖中沒有1,則回傳真,若有1,則回傳假
例:

2.8 all
函式原型:
bool all() const noexcept;
回傳值:若位圖中全為1,回傳真,否則回傳假
例:

2.9 set
函式原型:
bitset& set() noexcept; //將所有位元位全部置為1
bitset& set (size_t pos, bool val = true);//將pos位元位置為0或者1,默認為1
注意:若pos大于位圖位數,則會拋例外,out_of_range
例:


2.10 reset
函式原型:
bitset& reset() noexcept; //將所有位元位置為0
bitset& reset (size_t pos); //將pos位置置為0
注意:若pos大于位圖位數,則會拋例外,out_of_range
例:

2.11 filp
函式原型:
bitset& flip() noexcept; //全部位元位翻轉,0->1,1->0
bitset& flip (size_t pos); pos位元位翻轉,0->1,1->0
注意:若pos大于位圖位數,則會拋例外,out_of_range
例:

轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/262982.html
標籤:區塊鏈
上一篇:我的第一個Go程式
