简介

#include< bitset >
bitset是用来存放bit位元素的,由于每个元素(0或1)只占1bit位,因而可以节约空间(相比于8bit位的bool型变量)。在c++ stl中,提供了操作位的容器。

操作

1.创建

bitset<100> b//它能容纳100位比特位,每位上的初始值为0

bitset的大小在定义时确定,定义后不能修改
2.赋值

  • 下标法,b[i],下标i的取值从0到n-1
  • b.set(),对b中所有元素设置为1(默认为0)
  • b.reset(), 对b中所有元素设置为0
  • b.set(pos,val) 等价于 b[pos]=val
  • b.reset(pos) 等价于b[pos]=0

3.其他操作

  • test(pos) pos位是否为1? b.test(4)
  • any() 任意位是否为1? b.any()
  • none() 是否没有位为1? b.none()
  • count() 值是1的位数 b.count()
  • size() 位数 b.size()
  • flip() 翻转所有位 b.flip()
  • flip(pos) 翻转pos位 b.flip(4)

特性:

1.bitset存储二进制数位。
2.bitset就像一个bool类型的数组一样,但是有空间优化——bitset中的一个元素一般只占1 bit,相当于一个char元素所占空间的八分之一,可以当作一个bool型数组考虑,bitset<N> bs 可以考虑成一个数组bool bs[N]。
3.bitset中的每个元素都能单独被访问,例如对于一个叫做foo的bitset,表达式foo[3]访问了它的第4个元素,就像数组一样,这个访问是从数组后面开始访问的
4.bitset有一个特性:整数类型和布尔数组都能转化成bitset。

应用

位运算符 & | ^ ~ << 也适用于bitset,可在常数时间内进行运算

	bitset<4> foo (string("1001"));
    bitset<4> bar (string("0011"));

    cout << (foo^=bar) << endl;       // 1010 (foo对bar按位异或后赋值给foo)
    cout << (foo&=bar) << endl;       // 0010 (按位与后赋值给foo)
    cout << (foo|=bar) << endl;       // 0011 (按位或后赋值给foo)

    cout << (foo<<=2) << endl;        // 1100 (左移2位,低位补0,有自身赋值)
    cout << (foo>>=1) << endl;        // 0110 (右移1位,高位补0,有自身赋值)

    cout << (~bar) << endl;           // 1100 (按位取反)
    cout << (bar<<1) << endl;         // 0110 (左移,不赋值)
    cout << (bar>>1) << endl;         // 0001 (右移,不赋值)

    cout << (foo==bar) << endl;       // false (0110==0011为false)
    cout << (foo!=bar) << endl;       // true (0110!=0011为true)

    cout << (foo&bar) << endl;        // 0010 (按位与,不赋值)
    cout << (foo|bar) << endl;        // 0111 (按位或,不赋值)
    cout << (foo^bar) << endl;        // 0101 (按位异或,不赋值)

例题:牛客练习赛53 C-富豪凯匹配串

#include <bits/stdc++.h>
using namespace std;
const int N=1010;
bitset<N>c[N],A,B;
int n,m,q;
char s[N];
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%s",s);
        for(int j=0;j<m;j++)c[i][j]=s[j]-'0';
    }
    scanf("%d",&q);
    while(q--){
        scanf("%s",s);
        for(int i=0;i<m;i++){
            if(s[i]=='0')A[i]=1,B[i]=0;
            else if(s[i]=='1')A[i]=1,B[i]=1;
            else A[i]=0,B[i]=0;
        }
        int ans=0;
        for(int i=1;i<=n;i++){
            if((A&c[i])==B)ans++;
        }
        printf("%d\n",ans);
    }
}