跳转至

bitset

📌bitset

🧠 简述

  • $\texttt{bitset}$ 是 C++ 标准库中的高效位容器,用于存储固定大小的二进制数据($0/1$)
  • 提供接近硬件级别的位操作性能,特别适合状态压缩和布尔运算

存储原理

  • 内存按字节寻址,普通 $\texttt{bool}$ 类型每个值占用 $1$ 字节($8$ 比特)
  • $\texttt{bitset}$ 通过位压缩技术,每个比特存储一个 $0/1$ 值

空间效率

存储单个 $0/1$ 值仅需 $1$ 位空间

  • 相比 $\texttt{int}$ 类型($32$ 位/值),空间利用率提升 $32$ 倍
  • 相比 $\texttt{bool}$ 数组($8$ 位/值),空间利用率提升 $8$ 倍

性能优势

  • 单条机器指令可同时处理 $32/64$ 位数据(位级并行)
  • 批量操作(如移位、位运算)时间复杂度为 $O(n/w)$
  • $w$ = 机器字长($32$ 位或 $64$ 位)
  • 理论加速比最高可达 $w$ 倍

📘 创建和初始化

$\texttt{bitset}$ 的大小是在定义时指定的,且大小不可修改。

可以通过字符串或数字来初始化 $\texttt{bitset}$。

bitset<8> b1;           // 默认初始化为 00000000
bitset<8> b2("10101010"); // 从二进制字符串初始化
bitset<8> b3(10);        // 从整数初始化,10 的二进制表示为 00001010

输出:

cout << b1 << endl; // 输出: 00000000
cout << b2 << endl; // 输出: 10101010
cout << b3 << endl; // 输出: 00001010

支持的运算符

例如定义 $\texttt{bitset<8> b2("10101010")}$。

  • $\texttt{[]}$: 访问其特定的一位。例:$\texttt{cout << b[3]}$。
  • $\texttt{==}$ 和 $\texttt{!=}$:比较两个 $\texttt{bitset}$ 内容是否完全一样。
  • 位运算。$\texttt{bitset}$ 只能与 $\texttt{bitset}$ 进行位运算,若要和整型进行位运算,要先将整型转换为 $\texttt{bitset}$。

此外,$\texttt{bitset}$ 还提供了 C++ 流式 IO 的支持,这意味着你可以通过 $\texttt{cin/cout}$ 进行输入输出。

bitset<8> bs;
cin >> bs; // 输入必须是 01 字符串,且长度和 bitset 大小匹配。
cout << bs;
int num;
cin >> num;
bitset<32> bs(num); // 将整数转换为 32 位 bitset

⚙️ 常见函数

$\texttt{bitset}$ 提供了许多内置函数用于操作和查询二进制数据。

  • $\texttt{count()}$:返回 $\texttt{bitset}$ 中 1 的个数。
  • $\texttt{size()}$:返回 $\texttt{bitset}$ 的大小。
  • $\texttt{any()}$:如果 $\texttt{bitset}$ 中存在 $1$,则返回 true
  • $\texttt{none()}$:如果 $\texttt{bitset}$ 中所有位都为 $0$,返回 true
  • $\texttt{all()}$:如果 $\texttt{bitset}$ 中所有位都为 $1$,返回 true
  • $\texttt{flip()}$:反转所有位。$\texttt{b.flip(pos)}$:翻转某一位。
  • $\texttt{set()}$:将所有位设为 $1$。$\texttt{b.set(pos, true/false)}$:设置某一位的值。
  • $\texttt{reset()}$:将所有位设为 $0$。$\texttt{b.reset(pos)}$:设置某一位为 false
  • $\texttt{to_string()}$:将 $\texttt{bitset}$ 转换为二进制字符串。
  • $\texttt{to_ulong()}$:返回转换成的 $\texttt{unsigned long}$ 表达。
  • $\texttt{to_ullong()}$:返回转换成的 $\texttt{unsigned long long}$ 表达。
bitset<8> b("10101010");
cout << b.count() << endl;  // 输出: 4 (1 的数量)
cout << b.size() << endl; // 输出:8
cout << b.any() << endl;  // 输出: 1 (存在 1)
cout << b.none() << endl; // 输出: 0 (存在 1)
cout << b.all() << endl; // 输出:0(存在 0)
b.flip(); // b.flip(5)
b.set(); // b.set(5, 1)
b.reset(); // b.reset(5)

🧩 常用函数

函数 说明 示例
count() 返回 1 的数量 b.count()
size() 返回总位数 b.size()
any() 是否至少有一位为 1 b.any()
none() 是否全为 0 b.none()
all() 是否全为 1 b.all()
flip() 翻转所有位 b.flip()
flip(pos) 翻转第 pos b.flip(3)
set() 所有位设为 1 b.set()
set(pos, val) 设置第 pos 位为 val b.set(2, 0)
reset() 所有位设为 0 b.reset()
reset(pos) pos 位设为 0 b.reset(2)
to_string() 转为字符串(如 "0101..." b.to_string()
to_ulong() 转为 unsigned long b.to_ulong()
to_ullong() 转为 unsigned long long b.to_ullong()

转为其他类型

bitset<4> b(5);
unsigned long ul = b.to_ulong();
unsigned long long ull = b.to_ullong();
string s = b.to_string();  // 转为字符串

✅ 位运算

支持与、或、异或、非等位运算,可以高效地进行多个二进制数的运算。

两个长度为 $n$ 的 bitset 做位运算的时间复杂度为 $O(\frac{n}{w})$。

bitset<8> a("10101010");
bitset<8> b("11001100");

bitset<8> c = a & b;  // 按位与
bitset<8> d  = a | b;  // 按位或
bitset<8> e = a ^ b;  // 按位异或
bitset<8> f = ~a;     // 按位非

cout << c << endl;  // 输出: 10001000
cout << d << endl;   // 输出: 11101110
cout << e << endl;  // 输出: 01100110
cout << f << endl;  // 输出: 01010101
cout << (a << 3) << endl; // 输出:01010000
cout << (a >> 3) << endl; // 输出:00010101