A bitset is a special container class that is designed to store bits (elements with only two possible values: 0 or 1,true or false, ...).

bitset是一个特殊的容器专门用来存储bit

The class is very similar to a regular array, but optimizing for space allocation: each element occupies only one bit (which is eight times less than the smallest elemental type in C++: char).

Each element (each bit) can be accessed individually: for example, for a given bitset named mybitset, the expression mybitset[3] accesses its fourth bit, just like a regular array accesses its elements.

Because no such small elemental type exists in most C++ environments, the individual elements are accessed as special references which mimic模拟 bool elements:

class bitset::reference {
friend class bitset;
reference(); // no public constructor
public:
~reference();
operator bool () const; // convert to bool
reference& operator= ( bool x ); // assign from bool
reference& operator= ( const reference& x ); // assign from bit
reference& flip(); // flip bit value
bool operator~() const; // return inverse value
}

Apart from 除了overriding several operators and to provide direct access to the bits, bitsets have the feature of being able to be constructed from and converted to both integer values and binary strings (see constructor,bitset::to_ulong and bitset::to_string). They can also be directly inserted and extracted from streams in binary format.

Bitsets have a fixed size. For a similar container class that also optimizes for space allocation and allows for dynamic resizing, see the bool specialization of vector (vector<bool>).

In their implementation in the C++ Standard Template Library, bitsets take a single template parameter:

 
template < size_t N > class bitset;

Where the template parameter has the following meaning:

    • N: Number of bits to contain (size_t is an integral type).

      • 构造函数使用:
      • int main ()
        {
        bitset<> first; // empty bitset bitset<> second (120ul); // initialize from unsigned long bitset<> third (string("")); // initialize from string return ;
        }

 bitset的定义和初始化

表3-6列出了bitset的构造函数。类似于vector,bitset类是一种类模板;而与vector不一样的是bitset类型对象的区别仅在其长度而不在其类型。在定义bitset时,要明确bitset含有多少位,须在尖括号内给出它的长度值:

bitset<32> bitvec; //32位,全为0。

给出的长度值必须是常量表达式(2.7节)。正如这里给出的,长度值必须定义为整型字面值常量或是已用常量值初始化的整数类型的const对象。

这条语句把bitvec定义为含有32个位的bitset对象。和vector的元素一样,bitset中的位是没有命名的,程序员只能按位置来访问它们。位集合的位置编号从0开始,因此,bitvec的位序是从0到31。以0位开始的位串是低阶位(low-order bit),以31位结束的位串是高阶位(high-order bit)。

表3-6  初始化bitset对象的方法

bitset<n> b; b有n位,每位都为0
bitset<n> b(u); b是unsigned long型u的一个副本
bitset<n> b(s); b是string对象s中含有的位串的副本
bitset<n> b(s, pos, n); b是s中从位置pos开始的n个位的副本

头文件:

#include <bitset> 没有.h
using std::bitset;

bitset<10> third(string("01011")); //从string对象读入位集的顺序是从右向左: 11010 00000
cout<<third; 输出结果是:  11010 00000 cout bitset是从高位到地位。

cout << third[2] << endl; 从地位开始的,输出0

cout<<thrid[0]<<endl; 输出1

1. 用unsigned值初始化bitset对象

当用unsigned long值作为bitset对象的初始值时,该值将转化为二进制的位模式。而bitset对象中的位集作为这种位模式的副本。如果bitset类型长度大于unsigned long值的二进制位数,则其余的高阶位置为0;如果bitet类型长度小于unsigned long值的二进制位数,则只使用unsigned值中的低阶位,超过bitet类型长度的高阶位将被丢弃。

在32位unsigned long的机器上,十六进制值0xffff表示为二进制位就是十六个1和十六个0(每个0xf可表示为1111)。可以用0xffff初始化bitset对象:

// bitvec1 is smaller than the initializer
bitset<16> bitvec1(0xffff);          // bits 0 ... 15 are set to 1
// bitvec2 same size as initializer
bitset<32> bitvec2(0xffff);          // bits 0 ... 15 are set to 1; 16 ... 31 are 0
// on a 32-bit machine, bits 0 to 31 initialized from 0xffff
bitset<128> bitvec3(0xffff);         // bits 32 through 127 initialized to zero

上面的三个例子中,0到15位都置为1。由于bitvec1位数少于unsigned long的位数,因此bitvec1的初始值的高阶位被丢弃。bitvec2和unsigned long长度相同,因此所有位正好放置了初始值。bitvec3长度大于32,31位以上的高阶位就被置为0。

2. 用string对象初始化bitset对象

当用string对象初始化bitset对象时,string对象直接表示为位模式。从string对象读入位集的顺序是从右向左:

string strval("1100");
bitset<32> bitvec4(strval);

bitvec4的位模式中第2和3的位置为1,其余位置都为0。如果string对象的字符个数小于bitset类型的长度,则高阶位将置为0。

string对象和bitset对象之间是反向转化的:string对象的最右边字符(即下标最大的那个字符)用来初始化bitset对象的低阶位(即下标为0的位)。当用string对象初始化bitset对象时,记住这一差别很重要。

不一定要把整个string对象都作为bitset对象的初始值。相反,可以只用某个子串作为初始值:

string str("1111111000000011001101");
bitset<32> bitvec5(str, 5, 4); // 4 bits starting at str[5], 1100
bitset<32> bitvec6(str, str.size() - 4);     // use last 4 characters

这里用str中从str[5]开始包含四个字符的子串来初始化bitvec5。照常,初始化bitset对象时总是从子串最右边结尾字符开始的,bitvec5的从0到3的二进制位置为1100,其他二进制位都置为0。如果省略第三个参数则意味着取从开始位置一直到string末尾的所有字符。本例中,取出str末尾的四位来对bitvec6的低四位进行初始化。bitvec6其余的位初始化为0。这些初始化过程的图示如下:

更多:

http://book.51cto.com/art/200809/88698.htm

构造函数
bitset<n> b;
 b有n位,每位都为0.参数n可以为一个表达式.
如bitset<5> b0;则"b0"为"00000";
 cout<<b0; 输出5个0

bitset<n> b(unsigned long u);
 b有n位,并用u赋值;如果u超过n位,则顶端被截除
如:bitset<5>b0(5);则"b0"为"00101";

bitset<n> b(string s);
 b是string对象s中含有的位串的副本
string bitval ( "10011" );
bitset<5> b0 ( bitval4 );
则"b0"为"10011";

bitset<n> b(s, pos);
 b是s中从位置pos开始位的副本,前面的多余位自动填充0;
string bitval ("01011010");
bitset<10> b0 ( bitval5, 3 );
则"b0" 为 "0000011010";

bitset<n> b(s, pos, num);
 b是s中从位置pos开始的num个位的副本,如果num<n,则前面的空位自动填充0;
string bitval ("11110011011");
bitset<6> b0 ( bitval5, 3, 6 );
则"b0" 为 "100110";

os << b
 把b中的位集输出到os流
os >>b
输入到b中,如"cin>>b",如果输入的不是0或1的字符,只取该字符前面的二进制位.
(如:

bitset<8> e;
cin>>e;
cout<<e<<endl;

输入11110000,输出11110000)

bool any( ) 
 是否存在置为1的二进制位?和none()相反
 
bool none( ) 
是否不存在置为1的二进制位,即全部为0?和any()相反.
 
size_t count( )
二进制位为1的个数.
 
size_t size( )
 二进制位的个数

flip()
 把所有二进制位逐位取反
 
flip(size_t pos)
 把在pos处的二进制位取反
 
bool operator[](   size_type _Pos )
 获取在pos处的二进制位
 
set()
 把所有二进制位都置为1
 
set(pos,bool val=true)
 把在pos处的二进制位置为1。

pos:Order position of the bit whose value is modified.
Order positions are counted from the rightmost bit, which is order position 0.
If pos is equal or greater than the bitset size, an out_of_range exception is thrown.
size_t is an unsigned integral type.

注意pos,是从最右边开始数起。这一点千万有注意。

可以看到,set有2种原型,都返回当前的对象,demo:

// bitset::set
#include <iostream> // std::cout
#include <bitset> // std::bitset int main ()
{
std::bitset<> foo; std::cout << foo.set() << '\n'; //
std::cout << foo.set(2,0) << '\n'; // 1011
std::cout << foo.set() << '\n'; // return ;
}

输出:

1111
1011
1111)

reset()
 把所有二进制位都置为0
 
reset(pos)
 把在pos处的二进制位置为0

test(size_t pos) (也是从右边开始)
在pos处的二进制位是否为1?

unsigned long to_ulong( )
 用同样的二进制位返回一个unsigned long值

bitset<32> b(16);
cout<<b<<endl;
cout<<b.to_ulong()<<endl; 输出16

string to_string ()
返回对应的字符串.

详细请翻阅msdn.

http://www.cplusplus.com/reference/bitset/bitset/

Member functions

(constructor)
Construct bitset (public member function )
applicable operators
Bitset operators (function )

Bit access

operator[]
Access bit (public member function )
count
Count bits set (public member function )
size
Return size (public member function )
test
Return bit value (public member function )
any
Test if any bit is set (public member function )
none
Test if no bit is set (public member function )
all 
Test if all bits are set (public member function )

Bit operations

set
Set bits (public member function )
reset
Reset bits (public member function )
flip
Flip bits (public member function )

Bitset operations

to_string
Convert to string (public member function )
to_ulong
Convert to unsigned long integer (public member function )
to_ullong 
Convert to unsigned long long (public member function )

Non-member function overloads

applicable operators
Bitset operators (function )

Non-member class specializations

hash<bitset> 
Hash for bitset (class template specialization )

csdn上也有一篇写的很好,以下为链接
http://book.csdn.net/bookfiles/17/1001760.shtml

关于bitset最大size问题,我写了一个程序:

#include<iostream>
#include<bitset>
using namespace std; #define N 10000000 int main()
{
bitset<N> b; cout<<b<<endl;
}

一运行就崩溃,F5调试时发现stack overflow。

原因:vc默认1M的栈空间,可以在工程-》设置-》链接 栈分配 保留当中修改,比如0x9000000就代表栈最大9M。

我们定义的局部变量b是分配在stack空间的。超过了1M大小,所以stack overflow,当然我们可以更改stack大小。有没有其他的办法呢?

解决办法1:把bitset<N> 放到全局变量或加上static。(原因不言自明)

解决办法2:new一个bitset。

关于bitset<N>和vector<bool>区别:http://blog.csdn.net/liushu1231/article/details/8844631

c++ bitset使用的更多相关文章

  1. strtok源码 bitset 空间压缩

    源代码里有一段: unsigned char map[32]; /* Clear control map */ for (count = 0; count < 32; count++) map[ ...

  2. DFS序+线段树+bitset CF 620E New Year Tree(圣诞树)

    题目链接 题意: 一棵以1为根的树,树上每个节点有颜色标记(<=60),有两种操作: 1. 可以把某个节点的子树的节点(包括本身)都改成某种颜色 2. 查询某个节点的子树上(包括本身)有多少个不 ...

  3. 把《c++ primer》读薄(3-3 标准库bitset类型)

    督促读书,总结精华,提炼笔记,抛砖引玉,有不合适的地方,欢迎留言指正. //开头 #include <bitset> using std::bitset; 问题1.标准库bitset类型( ...

  4. BitSet构造函数的两种特例

    C++11之后,bitset的构造函数新加了两种形式: bitset<bits>::bitset (const string& str, string::size_type str ...

  5. Bitset<>用于unordered container时的默认hash函数

    自从c++11起,bitset用于unordered container,将会提供默认的hash函数. 在gcc中,相关代码如下: // DR 1182. /// std::hash speciali ...

  6. hdu 4920 Matrix multiplication bitset优化常数

    Matrix multiplication Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/ ...

  7. hdu 5506 GT and set dfs+bitset优化

    GT and set Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Probl ...

  8. (DFS、bitset)AOJ-0525 Osenbei

    题目地址 简要题意: 给出n行m列的0.1矩阵,每次操作可以将任意一行或一列反转,即这一行或一列中0变为1,1变为0.问通过任意多次这样的变换,最多可以使矩阵中有多少个1. 思路分析: 行数比较小,先 ...

  9. Gym 100917J---Judgement(01背包+bitset)

    题目链接 http://codeforces.com/gym/100917/problem/J Description standard input/outputStatements The jury ...

  10. C++二进制文件中读写bitset

    这个比较简单,直接上代码: bitset< > *b = >(); bitset< > *c = >(); ofstream out("I:\\test. ...

随机推荐

  1. 2014.8.16 if语句

    语句 if语句 大体可以分一下几种: 小知识  生成一个随机数: Random sss = new Random(); int a = sss.Next(100); Console.WriteLine ...

  2. 一个JAVA代码

    public class HelloJava { public static void main(String[] args) { System.out.println("这"); ...

  3. ubuntu下浏览器调用本地应用程序

    ubunut下浏览器调用本地应用程序需要desktop文件和scheme协议的支持,和windows 的url protocol类似,只是注册协议的方式不一样. 首先是desktop文件,里面需要加入 ...

  4. Spring学习之优缺点

    Spring 1.Spring工作机制及为什么要用? Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的.Spring既是一个AOP框架,也是一IOC容器. SpringFrame ...

  5. hdu 4034 Graph floyd

    题目链接 给出一个有向图各个点之间的最短距离, 求出这个有向图最少有几条边, 如果无法构成图, 输出impossible. folyd跑一遍, 如果dp[i][j] == dp[i][k]+dp[k] ...

  6. bzoj 1066 : [SCOI2007]蜥蜴 网络流

    题目链接 给一个n*m的图, 里面每一个点代表一个石柱, 石柱有一个高度. 初始时有些石柱上面有蜥蜴, 蜥蜴可以跳到距离他曼哈顿距离小于等于d的任意一个石柱上,跳完后, 他原来所在的石柱高度会减一, ...

  7. java中的四则运算

    代码的思路是通过正则判断计算每个最小的计算单元.以下是代码: package cn.com.lawchat.forpublicmvc.util; import java.math.BigDecimal ...

  8. C 查找子字符串

    自己用 C 写的一个查找子字符串的函数 int findstr(char *str,char *substr) //C实现 find{ if(NULL == str || NULL== substr) ...

  9. CVTE 一面

    在网上做完了测评之后,当天就收到面试的通知了,CVTE效率真高.第二天就去参加面试,面试前紧张了一把,后来去到之后发现只有几个应聘者,很多面试官前面都没人,估计现在中午一点,所以都去吃饭了.我和一个同 ...

  10. NYOJ 14 会场安排问题(也算是经典问题了)

    会场安排问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 学校的小礼堂每天都会有许多活动,有时间这些活动的计划时间会发生冲突,需要选择出一些活动进行举办.小刘的工作就 ...