简介
#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 (按位异或,不赋值)
#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);
}
}