浅析c++bitset的用法(代码片段)

shen12345678 shen12345678     2022-10-21     174

关键词:

浅析 c++ bitset 的用法

总述

C++的 \\(bitset\\) 位于 <bitset> 头文件中,这是一种类似于数组的数据结构,每个位置存储 \\(0\\ or\\ 1\\) ,并且每个元素仅用 \\(1\\ bit\\) 的空间

如果换一种方式来想,\\(bitset\\) 就是一个封装了一堆奇奇怪怪操作并支持状态压缩\\(bool\\) 数组,而且支持基本的位运算

定义 or 声明

bitset<4> bitset1;  //无参构造,长度为4,默认每一位为0
	
bitset<8> bitset2(12);  //长度为8,二进制保存,前面用0补充

/*用string对象初始化bitset*/
string s = "100101";
bitset<10> bitset3(s);  //长度为10,前面用0补充
    
/*用char对象初始化bitset*/
char s2[] = "10101";
bitset<13> bitset4(s2);  //长度为13,前面用0补充

bitset<2> bitset5(12) //12的二进制为1100(长度为4),但bitset1的size=2,只取后面部分,即00

cout << bitset1 << endl;	//0000
cout << bitset2 << endl;	//00001100
cout << bitset3 << endl;	//0000100101
cout << bitset4 << endl;	//0000000010101
cout << bitset5 << endl;	//00

需要注意的是:在用string去初始化的时候,string 中的字符只能为 \\(0\\ or\\ 1\\)

操作

1.运算

位操作符 的用法相同

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 (按位异或,不赋值)

2.访问

可以通过访问数组下标的形式访问 \\(bitset\\) 中的元素,注意最低位下标为 \\(0\\)

同时,也可以通过这种方式进行单点修改

bitset<4> foo ("1011");
    
cout << foo[0] << endl;	//1
cout << foo[1] << endl;	//1
cout << foo[2] << endl;	//0
cout << foo[3] << endl;	//1

3.一些函数的使用

bitset<1000> s;

s.count();	//返回s中1的个数

s.any();	//当s全为0时,返回false;如果有任何一位为1,则返回true
s.none();	//当s全为0时,返回true;如果有任何一位为1,则返回false

s.set();	//将s中每一位都设置为1
s.set(3,0);	//将s中第3位的数值设置为0
s.set(3);	//将s中第3位的数值设置为1

s.reset();	//将s中每一位都设置为0
s.flip();	//对s中每一位都取反

需要注意的是 s.reset()s.flip() 也可以传参数,和 s.set 的用法大致相同

4.一些操作

对于一类题,有这样的书写方式

s |= s << w[i]

这句代码实际上是将 \\(s\\) 左移了 \\(w[\\ i\\ ]\\) 位,并且与原来的 \\(s\\) 取并集

下面拿两道例题举举栗子

Luogu P2347 [NOIP1996 提高组] 砝码称重

#include <bits/stdc++.h>
using namespace std;
int w[10]=0,1,2,3,5,10,20,a[10];
bitset<1010> s;

int main()
	for(int i=1;i<=6;i++)
		cin>>a[i];
	s[0]=1;
	for(int i=1;i<=6;i++)
		for(int j=0;j<a[i];j++)
			s|=s<<w[i];
	cout<<"Total="<<s.count()-1<<endl;
	return 0;

Luogu P1441 砝码称重

#include <bits/stdc++.h>
using namespace std;
const int N=2010;
int a[50],n,m,ans;

inline int read()
	int f=1,x;
	char ch;
	while((ch=getchar())<\'0\'||ch>\'9\') if(ch==\'-\') f=-1;
	x=ch-\'0\';
	while(\'0\'<=(ch=getchar())&&ch<=\'9\') (x*=10)+=ch-\'0\';
	return x*f;


inline int cal(unsigned int x)
	int ret=0;
	while(x!=0)
		if(x&1) ret++;
		x>>=1;
	
	return ret;


int main()
	n=read(),m=read();
	for(int i=0;i<n;i++)
		//scanf("%d",&a);
		a[i]=read();
	for(int i=0;i<(1<<n);i++)
		if(cal(i)==n-m)
			bitset<N> s;
			s[0]=1;
			for(int j=0;j<n;j++)
				if(i&(1<<j))
					s|=s<<a[j];
			ans=max(ans,(int)s.count());
		
	
	cout<<ans-1<<endl;	
	return 0;

这两个题在对可以称出的质量进行统计的时候使用了这个小技巧,就可以摆脱 \\(dfs+dp\\) 的复杂方式,从而转化为 \\(bitset\\) 的一道题目,大大优化了时间复杂度和空间复杂度

浅析static(代码片段)

static前言一、static是什么?二、static的用法及作用1.static修饰局部变量2.static修饰全局变量3.static修饰函数总结前言C语言中有许多关键字,每个关键字都有着不同的作用以及意义,例如typedef的作用是起别名,const的... 查看详情

记录一个比较少用的容器c++std::bitset(代码片段)

bitset存储二进制数位。bitset就像一个bool类型的数组一样,但是有空间优化——bitset中的一个元素一般只占1bit,相当于一个char元素所占空间的八分之一。bitset中的每个元素都能单独被访问,例如对于一个叫做foo的bitset,表达式foo... 查看详情

暑假集训||bitset(代码片段)

bitset是一个存储0和1的数组可以快速的把两个bitset的每一位对应做与或啥的在可以用01串表示某个状态的时候可以应用到它就是有两个集合,求它们的交集bitset<6>a,b,c;a[1]=a[4]=a[5]=1;b[2]=b[4]=b[5]=b[6]=1;c=a&b;cout<<c<<endl;co... 查看详情

busybox浅析(代码片段)

title:busybox(一)浅析tag:armdate:2018-11-1323:02:33---busybox浅析源码包在busybox-1.7.0.tar.bz2,一个命令对应着一个c文件,执行init命令,则是有init.c,有函数init_mainintinit_main(intargc,char**argv);最终的目的是启动客户的应用程序,需要指定具体的... 查看详情

记一次由bitset引起的21发tle(代码片段)

1、直接用bitset进行&|^操作,它的效率取决于bitset的长度    长为1e5的bieset进行1e5次位运算,1s+2、any(),none()也与长度有关    长为1e5的bitset进行1e5次,0.8s+3、all()取决于里面1的数量,如果全是1的话... 查看详情

浅析c/c++编译流程(代码片段)

...c;请看音视频系统学习的浪漫马车之总目录C/C++编译浅析C/C++编译本质一篇文章入门C/C++自动构建利器之Makefile升级构建工具,从Makefile到CMake如果你愿意一层一层一层地剥开我的心你会发现你会讶异你是我最... 查看详情

bitset与字串(代码片段)

之前有过区域赛,简化版问题:给定一个小写字符组成的字符串S,(|S|<1e5,下标从1开始),现在有Q种操作,对于每个操作Q(Q<=1e3),输入opt,如果opt==1,输入x,c,表示把S[x]改为c,(c是小写字母)。如果opt==2,输入字符串T... 查看详情

c++primer5th笔记(chap17标准库特殊设施)bitset类型(代码片段)

1.提取bitset的值函数返回一个值,保存了与bitset对象相同的位模式。to_ulong()//返回unsignedlongto_ullong()//返回unsignedlonglong只有当bitset的大小小于等于对应的大小时,我们才能使用这两个操作(如果bitset中的值不能放入给... 查看详情

c++primer5th笔记(chap17标准库特殊设施)bitset类型(代码片段)

1.定义bitset类是一个类模板,类似array类,用来处理二进制位的有序集。元素类型是固定的,是一个二进制位尖括号中输入的是bitset的长度而不是元素类型,大小必须是一个常量表达式编号从0开始的二进制位被称... 查看详情

bitset常用函数(代码片段)

bitset常用函数什么是bitsetbitset存储二进制数位。bitset中的一个元素一般只占1bit。bitset中的每个元素都能单独被访问,整数类型和布尔数组都能转化成bitset。bitset的大小在编译时就需要确定。如果你想要不确定长度的bitset,请使... 查看详情

busybox浅析(代码片段)

目录busybox(一)浅析引入读取inittab创建执行脚本链表执行脚本小结title:busybox(一)浅析tag:armdate:2018-11-1323:02:33---busybox(一)浅析源码包在busybox-1.7.0.tar.bz2,一个命令对应着一个c文件,执行init命令,则是有init.c,有函数init_mainintinit_main(intar... 查看详情

bipartitegraphhdu5313bitset并查集二分图(代码片段)

...问最多添加多少条边使之构成一个完全二分图存储结构:bitset  【用法详情:http://blog.csdn.net/piaocoder/article/details/47177891】用时:624ms思路:二分图的总边数即:n*m(假设 查看详情

linkedhashset浅析(代码片段)

LinkedHashSet浅析LinkedHashSet的继承linkedhashset继承了hashset,并实现了可克隆和可序列化publicclassLinkedHashSet<E>extendsHashSet<E>implementsSet<E>,Cloneable,java.io.Serializable LinkedHashSet的构造方法publicLinkedHashSet(intinitialCapacity,floatload... 查看详情

bitset学习(代码片段)

Bitset学习0.类模板1.定义#include<bitset>//头文件constintN=10;//以下两种都可以bitset<N>b;bitset<10>b;2.初始化字符串若位不足也是高位补0.字符串中若出现除0,1的其他数则程序会抛出异常.a.字符串初始化bitset<3>a("10111&... 查看详情

dagger2源码浅析(代码片段)

dagger2是目前android端比较火的一款依赖注入框架,先来看下基本的用法吧:首先提供module,类似于工厂:@ModulepublicclassApiServiceModuleprivatestaticfinalStringENDPOINT="";@Singleton@ProvidespublicOkHttpClientproviderOkHttpClient()OkHttpClientokHttpClient=newOkHttp... 查看详情

gym-100342j:triatrip(bitset加速求三元环的数量)(代码片段)

...区别不大。) 枚举代码:#include<cstdio>#include<bitset>#include<cstdlib>#includ 查看详情

hihocoder-1513bitset处理五维偏序(代码片段)

题意:给出(n<3e4)个有序组((a,b,c,d,e)),求对第(i)个有序组有多少个(j)满足((a_j<a_i,b_j<b_i,c_j<c_i,d_j<d_i,e_j<e_i))五维偏序问题按套路来可以排序+树套树套树套树(打死然而这是显然连(O(n^2))暴力都不如的可是题目给4s,(O(n^2))是... 查看详情

bitset用法

bitset了以容纳任意个数个位,并提供各项操作一、初始化bitset<16>b1; bitset<16>b2(25); bitset<16>b3(str,2,16);16表示有16位,不足的高位补0二、容量b1.size();也就是16b1.count();1的个数三、位判断b1.any();判断是否有1b1.none();判断是... 查看详情