如何深入理解并运用C语言中的bitset操作?

2026-05-17 01:401阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1486个文字,预计阅读时间需要6分钟。

如何深入理解并运用C语言中的bitset操作?

浅析C++中的bitset用法概述:

如何深入理解并运用C语言中的bitset操作?

C++的bitset是一种高效存储位数据的容器。在bitset头文件中定义,它类似于数组,但每个元素只占用一个位。每个位只能存储0或1,非常适合用于表示二进制信息。

用法说明:- 使用bitset定义时,需要指定位数。例如,`bitset bits;`定义了一个8位的bitset。- bitset中的元素默认都是0。- 可以使用索引访问bitset中的元素,例如`bits[3]`访问第4个位置的位。- 通过赋值操作可以将bitset的某个位置设置为1或0,例如`bits[5]=1;`。- bitset提供了成员函数用于操作位,如`set()`设置位为1,`reset()`设置为0,`flip()`翻转位,`test()`检查位是否为1。

例如,以下是一个简单的使用bitset的例子:

cpp#include

int main() { bitset bits; bits.set(); // 设置所有位为1 bits.reset(3); // 将第4个位置的位设置为0 bits.flip(); // 翻转所有位 bits.test(4) ? std::cout << 第5位是1 <

注意:在实际使用中,bitset非常适合处理与位操作相关的问题,如错误检测、数据压缩等。

浅析 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\) 的一道题目,大大优化了时间复杂度和空间复杂度

本文共计1486个文字,预计阅读时间需要6分钟。

如何深入理解并运用C语言中的bitset操作?

浅析C++中的bitset用法概述:

如何深入理解并运用C语言中的bitset操作?

C++的bitset是一种高效存储位数据的容器。在bitset头文件中定义,它类似于数组,但每个元素只占用一个位。每个位只能存储0或1,非常适合用于表示二进制信息。

用法说明:- 使用bitset定义时,需要指定位数。例如,`bitset bits;`定义了一个8位的bitset。- bitset中的元素默认都是0。- 可以使用索引访问bitset中的元素,例如`bits[3]`访问第4个位置的位。- 通过赋值操作可以将bitset的某个位置设置为1或0,例如`bits[5]=1;`。- bitset提供了成员函数用于操作位,如`set()`设置位为1,`reset()`设置为0,`flip()`翻转位,`test()`检查位是否为1。

例如,以下是一个简单的使用bitset的例子:

cpp#include

int main() { bitset bits; bits.set(); // 设置所有位为1 bits.reset(3); // 将第4个位置的位设置为0 bits.flip(); // 翻转所有位 bits.test(4) ? std::cout << 第5位是1 <

注意:在实际使用中,bitset非常适合处理与位操作相关的问题,如错误检测、数据压缩等。

浅析 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\) 的一道题目,大大优化了时间复杂度和空间复杂度