STL bitset

本文作者MiserWeyte

由於之前的洛谷月賽 20191109中我bitset不熟,直接導致了T3\(70 \sim 100pts \rightarrow 50pts\)。複習一下bitset。


一、概念

A bitset stores bits.

因此,bitset可以理解爲一個bool數組,但是速度更快,可以直接像一個整數一樣進行位運算,或者統計1的個數等。

二、聲明與初始化

bitset聲明,傳入的變量n爲bitset長度:

#include <bitset>
bitset <n> b; // 全爲0
bitset <n> b(u); // 從unsigned long型變量u複製而來
bitset <n> b(s); // 從string對象s複製而來
bitset <n> b(s, pos, m); // 從string對象s的[pos, pos+m]複製而來

使用unsigned long初始化的幾個例子:

bitset<16> bitvec1(0xffff); // bits 0 ... 15 are set to 1
// bitvec2 same size as initializer
bitset<32> bitvec2(0xffff); // bits 0 ... 15 are set to 1; 16 ... 31 are 0
// on a 32-bit machine, bits 0 to 31 initialized from 0xffff
bitset<128> bitvec3(0xffff); // bits 32 through 127 initialized to zero

使用unsigned long或者string初始化時,原始類型會被轉換爲位模式,以二進制形式對應bitset的初始位,超出指定bitset長度的部分捨棄。

三、操作

本節翻譯自c++ reference

1.訪問

  • b[pos]:訪問b的第pos位

  • b.count():統計1的個數
  • b.size():返回bitset位數
  • b.test(pos):返回b[pos]的值
  • b.any():檢驗是否有任何1
  • b.none():檢驗是否無任何1
  • b.all():檢驗是否均爲1(c++ 11)

2.修改

  • b.set(pos):將b[pos]修改爲1
    • 若不傳入pos,將所有位修改爲1
  • b.reset(pos):將b[pos]修改爲0
    • 若不傳入pos,將所有位修改爲0
  • b.flip(pos):將b[pos]取反
    • 若不傳入pos,將所有位逐位取反

3.轉化

  • b.to_string():轉化爲string
  • b.to_ulong():轉化爲unsigned long
  • b.to_ullong():轉化爲unsigned long long(c++ 11)

4.輸出

  • os << b:將b輸出到os流
    • 示例輸出如下
bitset <16> b(0xff);
cout << b;
///////////////////////////////////////////////
//output:
//0000000011111111
///////////////////////////////////////////////

5.位操作

bitset支持位操作符,基本上可以看作一個整型來處理。

一段c++ reference的樣例

// bitset operators
#include <iostream>       // std::cout
#include <string>         // std::string
#include <bitset>         // std::bitset

int main ()
{
  std::bitset<4> foo (std::string("1001"));
  std::bitset<4> bar (std::string("0011"));

  std::cout << (foo^=bar) << '\n'; // 1010 (XOR,assign)
  std::cout << (foo&=bar) << '\n'; // 0010 (AND,assign)
  std::cout << (foo|=bar) << '\n'; // 0011 (OR,assign)

  std::cout << (foo<<=2) << '\n';  // 1100 (SHL,assign)
  std::cout << (foo>>=1) << '\n';  // 0110 (SHR,assign)

  std::cout << (~bar) << '\n';     // 1100 (NOT)
  std::cout << (bar<<1) << '\n';   // 0110 (SHL)
  std::cout << (bar>>1) << '\n';   // 0001 (SHR)

  std::cout << (foo==bar) << '\n'; // false (0110==0011)
  std::cout << (foo!=bar) << '\n'; // true  (0110!=0011)

  std::cout << (foo&bar) << '\n';  // 0010
  std::cout << (foo|bar) << '\n';  // 0111
  std::cout << (foo^bar) << '\n';  // 0101

  return 0;
}
///////////////////////////////////////////////////////
//output:
//1010
//0010
//0011
//1100
//0110
//1100
//0110
//0001
//0
//1
//0010
//0111
//0101
///////////////////////////////////////////////////////
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章