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. scala io,ubuntu常见配置

      Ubuntu的scala环境配置 配置scala环境变量同时需要配置java的环境变量 配置方法: 1.先下载linux的相应版本的jdk与scala的二进制压缩包并解压. 解压方法: 先到jdk ...

  2. Listview 多个ViewHolder实现

    简单代码示例: package com.edaixi.adapter; import android.content.Context; import android.view.View; import ...

  3. codeforces 631D. Messenger kmp

    题目链接 首先想到kmp, 和普通的不一样的是,中间部分严格相等, 头和尾的字符相等但是数量可以不相等. 所以应该把子串的头和尾先去掉,然后对剩下的部分进行kmp. 子串长度为1或2要特别讨论. 不要 ...

  4. python collections中Counter类

    Counter是dict的一个子类,因此具有dict的属性与方法.如常用的iteritems, items, get, pop. class Counter(dict): 如果Key不存在,将返回0, ...

  5. 10_Segue Example

    10 // // ViewController.swift // Segues Example // // Created by ZC on 16/1/10. // Copyright © 2016年 ...

  6. 阿里云ECS每天一件事D9:nginx1.7整合tomcat8.0

    仅通过8080端口访问jsp显然不是一算是一个太好的方法,可以使用nginx的proxy_pass子模块,实现nginx转发jsp请求至tomcat. 典型的配置如下: server { listen ...

  7. C++读写EXCEL文件OLE,java读写excel文件POI 对比

    C++读写EXCEL文件方式比较 有些朋友问代码的问题,将OLE读写的代码分享在这个地方,大家请自己看.http://www.cnblogs.com/destim/p/5476915.html C++ ...

  8. Android发展简单介绍

    Android一词的本义指“机器人”,同一时候也是Google于2007年11月5日宣布的基于Linux平台的开源手机操作系统的名称,该平台由操作系统.中间件.用户界面和应用软件组成,号称是首个为移动 ...

  9. MongoDB(三)mongoDB下载和安装

    软件下载 下载mongodb最新的包:http://www.mongodb.org/downloads 下载mongodb可视化界面,mongoVUE:http://download.csdn.net ...

  10. 一步一步学c#(五):泛型

    泛型 性能 泛型的一个重要的优点是性能.system.collections和system.collections.generic名称空间的泛型和非泛型集和类.对值类型使用非泛型集合类,在把值类型转换 ...