C++基础之bitset

类模板std::bitset

template class bitset;

头文件

#include

说明

一个bitset中保存了一些bit(字节, 只能取两个值的元素:0或1,真或假 …)
bitset模拟了一个bool类型的数组,但是优化了内存空间:总的来说,每个元素值占用一个bit(比大多数系统中最小的元素char小了8倍)
每个位置的都可以独立的访问:例如,给定一个bitset命名为foo,foo[3]访问的就是第四个元素,就像通常数组访问他的元素一样。
但是因为在C++中没有只占用一个字节的类型,bitset是通过专门的引用类型来实现每个元素单独访问的(可以查看bitset::reference)。
bitset可以通过integer值和二元内容的字符串来创建,也可以转换为interger值和字符串(查看bitset的构造函数和to_ulong、to_sting方法)。可以插入到内容为二元类型的流中,也可以从二元类型的流中提取(查看bitset适用的操作符)。
bitset的大小在编译阶段就已经确定(由模板的参数决定)。对于同样对空间进行优化并且可以动态改变大小的类,可以使用一个专门为bool类型创建的vector 类(vector)。

模板类的参数

N:指定bitset的大小,根据所占bit的数量。可以通过bitset的成员函数bitset::size来获取。size_t是一个无符号整型。

成员类型

reference

像一个类型来引用。
这是一个嵌入式类,当在一个非const的bitset对象上使用下标操作符bitset::operator[]来访问元素的时候会返回该类型。通过一个模拟指向bool类型引用的接口来访问每个元素。
原型定义:

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

成员函数

构造函数(c++11)

函数原型
C++基础之bitset_第1张图片构造一个bitset容器对象:
1.默认构造函数: 对象中的值都设置为0
2.由integer值初始化bitset对象: 使用val对应的bit值来初始化bitset对象,参考例子
3.使用string或着(4)中的C-string来初始化对象: 使用str中的0和(或)1的序列来初始化bitset对象的前n个值。
注意: 不管用哪个构造函数构造出来的bitset对象的大小是不可变的(大小由类模板的参数决定)。没有被构造函数赋值的位会被初始化为0。
参数
val: 将integer类型值对应的bits位的值拷贝到bitset对象的对应位置。
1.如果val的位数大于bitset的size大小,只将val的低位的size个bit赋值给bitset
2.如果val的位数小于bitset的size大小,不足的部分补零。
str: 用来初始化bitset对象的string或这C-string。构造函数最多解析字符串的n个字符(第三个构造函数是从pos的位置开始读取),然后依次将每个字符的值解析为0和1。【注意】最后读取的字符赋值给最低有效位,字符串下标0在高有效位(参考例子)。因此bitset的第一位的值是string的最右边的值,然后从右到左一次读取。如果string序列比bitset的size小,剩余的补零。
pos: 从string读取的起始位置,如果超过了str的长度会抛出out_of_range的异常。
zero,one: 来表示0和1的字符。
Example:

// constructing bitsets
#include        // std::cout
#include          // std::string
#include          // std::bitset
int main () {
  std::bitset<16> foo;
  std::bitset<16> bar (0xfa2);
  std::bitset<16> baz (std::string("0101111001"));

  std::cout << "foo: " << foo << '\n';
  std::cout << "bar: " << bar << '\n';
  std::cout << "baz: " << baz << '\n';

  return 0;
}

Output:

foo: 0000000000000000
bar: 0000111110100010
baz: 0000000101111001

数据竞争
构造函数3和4中会访问str中的字符。
异常和安全
1和2构造函数不会抛出异常。3和4在pos大于length的时候会抛出out_of_length的异常。

适用的操作符(C++11)

C++基础之bitset_第2张图片对bitset中的内容执行逐位的操作。
参数
lhs: 操作符左侧的bitset对象(操作符不会修改该值)
rhs: 操作符右边的bitset对象,操作符左侧和右侧的bitset对象的size必须相同(类模板的N相等)。
pos: 要移动的位数
is,os: 读取bitset流和bitset写入的流,流必须是0和1字符序列
返回值
1.如果是一个引用,返回左侧值(*this,is或者os)。其他情况返回操作符的执行结果(可能是一个bitset对象,或者true、false)。
Example

// bitset operators
#include        // std::cout
#include          // std::string
#include          // std::bitset

int main ()
{
  std::bitset<4> foo (std::string("1001"));
  std::bitset<4> bar (std::string("0011"));

  std::cout << (foo^=bar) << '\n';       // 1010 (XOR,assign)
  std::cout << (foo&=bar) << '\n';       // 0010 (AND,assign)
  std::cout << (foo|=bar) << '\n';       // 0011 (OR,assign)

  std::cout << (foo<<=2) << '\n';        // 1100 (SHL,assign)
  std::cout << (foo>>=1) << '\n';        // 0110 (SHR,assign)

  std::cout << (~bar) << '\n';           // 1100 (NOT)
  std::cout << (bar<<1) << '\n';         // 0110 (SHL)
  std::cout << (bar>>1) << '\n';         // 0001 (SHR)

  std::cout << (foo==bar) << '\n';       // false (0110==0011)
  std::cout << (foo!=bar) << '\n';       // true  (0110!=0011)

  std::cout << (foo&bar) << '\n';        // 0010
  std::cout << (foo|bar) << '\n';        // 0111
  std::cout << (foo^bar) << '\n';        // 0101

  return 0;
}

Output:

1010
0010
0011
1100
0110
1100
0110
0001
0
1
0010
0111
0101

数据竞争
操作中bitset的所有位都会被访问,如果涉及赋值的,值会被修改。
异常&安全
流插入和提取的时候如果出现异常保持所有对象处于有效状态(基本保证)。其他不会抛出异常

访问bit

下标操作符([])

函数原型

 bool operator[] (size_t pos) const;
reference operator[] (size_t pos);

功能:
返回pos位置的值(或在引用)。该操作不会检查边界。bitset::test在访问值的同时会检查边界。
参数:
pos: pos位置的bit值。如果bitset对象是const的,该函数返回一个bool值。否则的花返回一个引用,该引用模拟了一个bool的值。
Example

// bitset::operator[]
#include        // std::cout
#include          // std::bitset

int main ()
{
  std::bitset<4> foo;

  foo[1]=1;             // 0010
  foo[2]=foo[1];        // 0110

  std::cout << "foo: " << foo << '\n';

  return 0;
}

Output:

foo: 0110

数据竞争
不管bitset是不是const的,只访问都不会修改bitset。非const版本返回的引用可以用来访问和修改bitset的内容。注意,修改一个位可能会对其他的位产生影响,因此并发访问bitset的不同位不是线程安全的。
异常&安全
如果指定的pos是无效的会导致不确定的行为。如果该函数出现异常,bitset仍保持有效状态(基本保证)。

std::bitset::count

函数原型(C++11)

size_t count() const noexcept;

功能
返回bitset中设置的有效位的数量(值为1的)。获取bitset的所有成员数量(包含值为0的),使用bitset::size.
参数

返回值
bitset中值为1的成员数量。size_t是unsigned integer类型。
Example

// bitset::count
#include        // std::cout
#include          // std::string
#include          // std::bitset

int main ()
{
  std::bitset<8> foo (std::string("10110011"));

  std::cout << foo << " has ";
  std::cout << foo.count() << " ones and ";
  std::cout << (foo.size()-foo.count()) << " zeros.\n";

  return 0;
}

Output:

10110011 has 5 ones and 3 zeros.

数据竞争
bitset会被访问。
异常&安全
强保证:如果该函数出现异常,对bitset没有任何影响。
如果bitset的长度超出了size_t的表示范围,则抛出overflow_error的异常。

std::bitset::size

函数原型(C++11)

constexpr size_t size() noexcept;

功能
返回bitset中所有成员数量(包含值为0的),值等于创建bitset对象的时候传入的参数N。
参数

返回值
bitset中所有的成员数量。size_t是unsigned integer类型。
Example

// bitset::size
#include        // std::cout
#include          // std::bitset

int main ()
{
  std::bitset<8> foo;
  std::bitset<4> bar;

  std::cout << "foo.size() is " << foo.size() << '\n';
  std::cout << "bar.size() is " << bar.size() << '\n';

  return 0;
}

Output:

foo.size() is 8
bar.size() is 4

数据竞争
无,在编译阶段确定的常量。
异常&安全
保证该函数不会抛出异常。

std::bitset::test

函数原型

bool test (size_t pos) const;

功能
返回bitset的pos下标位置是否被置位(值是不是1)。与下标操作符[]不同的是,test在访问值之前会检查pos是否有效,如果超过了bitset的size会抛出out_of_range的异常。
参数
pos: 要访问的值的下标。从最右侧的位置开始,下标从0开始。size_t是一个unsigned int类型。
返回值
如果置位了返回True,否则返回False。
Example

// bitset::test
#include        // std::cout
#include          // std::string
#include         // std::size_t
#include          // std::bitset

int main ()
{
  std::bitset<5> foo (std::string("01011"));

  std::cout << "foo contains:\n";
  std::cout << std::boolalpha;
  for (std::size_t i=0; i

Output:

foo contains:
true
true
false
true
false

数据竞争
bitset会被访问。
异常&安全
强保证:如果该函数出现异常,不会对bitset对象有任何的修改。
如果pos超出size会抛出out_of_range的异常。

std::bitset::any

函数原型

bool any() const noexcept;

功能
检测bitset中有没有被置1的位(bitset中至少有一个位被置为1)。
与函数bitset::none的功能正好相反。
参数

返回值
如果任意一位被置1的话返回True,否则返回False。
Example

// bitset::any
#include        // std::cin, std::cout
#include          // std::bitset

int main ()
{
  std::bitset<16> foo;

  std::cout << "Please, enter a binary number: ";
  std::cin >> foo;

  if (foo.any())
    std::cout << foo << " has " << foo.count() << " bits set.\n";
  else
    std::cout << foo << " has no bits set.\n";

  return 0;
}

Possible output:

Please, enter a binary number: 10110
0000000000010110 has 3 bits set.

数据竞争
bitset会被访问。
异常&安全
保证不会抛出任何异常。

std::bitset::none

函数原型(C++11)

bool none() const noexcept;

功能
检测bitset中全部为0。与函数bitset::any的功能正好相反。
参数

返回值
如果值全部为0返回True,否则返回False.
Example

// bitset::none
#include        // std::cin, std::cout
#include          // std::bitset

int main ()
{
  std::bitset<16> foo;

  std::cout << "Please, enter a binary number: ";
  std::cin >> foo;

  if (foo.none())
    std::cout << foo << " has no bits set.\n";
  else
    std::cout << foo << " has " << foo.count() << " bits set.\n";

  return 0;
}

Possible output:

Please, enter a binary number: 11010111
0000000011010111 has 6 bits set.

数据竞争
bitset会被访问。
异常&安全
保证不会抛出任何异常。

std::bitset::all(C++11)

函数原型

bool all() const noexcept;

功能
检测bitset中全部为1。如果返回True,bitset中size个元素全部被置位。
参数

返回值
如果值全部为1返回True,否则返回False.
Example

// bitset::all
#include        // std::cin, std::cout, std::boolalpha
#include          // std::bitset

int main ()
{
  std::bitset<8> foo;

  std::cout << "Please, enter an 8-bit binary number: ";
  std::cin >> foo;

  std::cout << std::boolalpha;
  std::cout << "all: " << foo.all() << '\n';
  std::cout << "any: " << foo.any() << '\n';
  std::cout << "none: " << foo.none() << '\n';

  return 0;
}

Possible output:

Please, enter an 8-bit binary number: 11111111
all: true
any: true
none: false

数据竞争
bitset会被访问。
异常&安全
保证不会抛出任何异常。

bit的操作函数

std::bitset::set

函数原型(C++11)

all bits (1)	bitset& set() noexcept;
single bit (2)	bitset& set (size_t pos, bool val = true);

功能
设置bitset中的值:
1.将bitset中的所有值设置为1。
2.将pos位置的bit的值设置为1。
参数
pos: 指定要修改的bit的下标位置。下标从0开始,由最右边开始标记。如果pos大于等于bitset的size则会抛出out_of_range的异常。
size_t是unsigned int类型。
val: 要赋的值(或者为True、1或者为False、0)
返回值
*this
Example

// bitset::set
#include        // std::cout
#include          // std::bitset

int main ()
{
  std::bitset<4> foo;

  std::cout << foo.set() << '\n';       // 1111
  std::cout << foo.set(2,0) << '\n';    // 1011
  std::cout << foo.set(2) << '\n';      // 1111

  return 0;
}

Output:

1111
1011
1111

数据竞争
bitset的位会被修改
异常&安全
函数1不会抛出任何异常。如果2出现异常,基本保证bitset仍处于有效状态。
如果pos大于等于bitset的size则会抛出out_of_range的异常。

std::bitset::reset

函数原型(C++11)

all bits (1)	bitset& reset() noexcept;
single bit (2)	bitset& reset (size_t pos);

功能
将bitset中的值为0:
1.将bitset中的所有值设置为0。
2.将pos位置的bit的值设置为0。
参数
pos: 指定要修改的bit的下标位置。下标从0开始,由最右边开始标记。如果pos大于等于bitset的size则会抛出out_of_range的异常。
size_t是unsigned int类型。
返回值
*this
Example

// bitset::reset
#include        // std::cout
#include          // std::string
#include          // std::bitset

int main ()
{
  std::bitset<4> foo (std::string("1011"));

  std::cout << foo.reset(1) << '\n';    // 1001
  std::cout << foo.reset() << '\n';     // 0000

  return 0;
}

Output:

1001
0000

数据竞争
bitset的位会被修改
异常&安全
函数1不会抛出任何异常。如果2出现异常,基本保证bitset仍处于有效状态。
如果pos大于等于bitset的size则会抛出out_of_range的异常。

std::bitset::flip

函数原型(C++11)

all bits (1)	bitset& flip() noexcept;
single bit (2)	bitset& flip (size_t pos);

功能
将bitset中的值取反:
1.将bitset中的所有值取反。
2.对指定位置pos的值取反。
参数
pos: 指定要取反的bit的下标位置。下标从0开始,由最右边开始标记。如果pos大于等于bitset的size则会抛出out_of_range的异常。
size_t是unsigned int类型。
返回值
*this
Example

// bitset::flip
#include        // std::cout
#include          // std::string
#include          // std::bitset

int main ()
{
  std::bitset<4> foo (std::string("0001"));

  std::cout << foo.flip(2) << '\n';     // 0101
  std::cout << foo.flip() << '\n';      // 1010

  return 0;
}

Output:

0101
1010

数据竞争
bitset的位会被修改
异常&安全
函数1不会抛出任何异常。如果2出现异常,基本保证bitset仍处于有效状态。
如果pos大于等于bitset的size则会抛出out_of_range的异常。

bitset的操作函数

std::bitset::to_string

函数原型(C++11)

template ,
                       class Alloc = allocator>
  basic_string to_string (charT zero = charT('0'),
                                              charT one  = charT('1')) const;

功能
构造一个基础string类型对象,将bitset中的值表示为一连串的0和/或1。
该函数返回的字符串与将bitset写入到<<输出操作符得到的显示结果是相同的。
注意:该函数使用函数模板来定义返回值。默认的返回值是string。
参数
zero, one: 用来表示0和1的字符。
返回值
用来表示bitset内容的字符串。
Example

// bitset::to_string
#include        // std::cout
#include          // std::string
#include          // std::bitset

int main ()
{
  std::bitset<4> mybits;     // mybits: 0000
  mybits.set();              // mybits: 1111

  std::string mystring =
    mybits.to_string();

  std::cout << "mystring: " << mystring << '\n';

  return 0;
}

Output:

mystring: 1111

数据竞争
会访问bitset对象。
异常&安全
强保证:如果该函数出现异常,对bitset没有任何的影响。

std::bitset::to_ulong

函数原型

unsigned long to_ulong() const;

功能
将bitset转换为unsigned long int。返回的unsigned long int对应的二进制序列与bitset中的序列相同。
如果bitset的size太大,用unsigned long int表示不了,会抛出一个overflow_error的异常。
参数

返回值
二进制序列与bitset相同的unsigned long int值。
Example

// bitset::to_ulong
#include        // std::cout
#include          // std::bitset

int main ()
{
  std::bitset<4> foo;     // foo: 0000
  foo.set();              // foo: 1111

  std::cout << foo << " as an integer is: " << foo.to_ulong() << '\n';

  return 0;
}

Output:

1111 as an integer is: 15

数据竞争
会访问bitset对象的内容。
异常&安全
强保证:如果该函数出现问题,不会对bitset对象有任何的影响
如果size太大导致超出unsigned long int的表示范围会抛出overflow_error的异常。

std::bitset::to_ullong(C++11)

该函数与std::bitset::to_ulong的区别就是该函数会返回一个unsigned long long类型,其他使用方式和注意事项相同,不再重复叙述。

定制非成员类

std::hash(C++11)

函数原型

template  struct hash;              // unspecialized
template  struct hash>;  // bitset specialization

bitset的hash计算。是一个一元函数的类对象,bitset定制的hash函数计算函数。

函数根据传入的bitset返回一个哈希值:哈希值的只与传入的参数有关,相同的参数返回相同的值(对于已给定的计算方式)。不同参数的返回值应该尽量不同(碰撞可能性接近1/numeric_limits::max)。
这就可以使用bitset对象作为无序容器的key(例如unordered_set 或者unordered_map)。
想了解更多可参考hash的实现

成员函数
()操作符:返回一个哈希值,类型为size_t,一个unsigned int类型的值。

你可能感兴趣的:(每天一点C++)