bitset、bitmap
一、bitset
一种类似数组的结构,它的每一个元素只能是0或1,每个元素仅用1bit空间。
1.构造
std::bitset<size> myBitset;
构造时必须用size声明bitset的大小,构造时可以用std::string,char*,ulonglong等初始化(string和char初始化时必须只包含0和1,否则抛出异常)
示例
std::bitset<4> b1(123); //十进制123 = 二进制01111011,所以b1是1101(从第0个元素开始算起)
//std::bitset<4> b2("ss"); //抛出异常
std::bitset<4> b3(0x4); //16进制4 = 二进制100,b3 = 0010,高位不够用0补齐
std::bitset<4> b4("11110000"); //只取4位 b4 = 1111
2.常用函数
函数 | 描述 |
---|---|
count() | 求bitset中1的个数 |
size() | 求bitset的大小 |
test(size_t pos) | 检查下标为pos处的值,0输出false |
any() | bitset是否含有1 |
none() | bitset中是否没有1 |
all() | bitset是否全部为1 |
示例
bitset<8> foo("10011011");
cout << foo.count() << endl; //5(count函数用来求bitset中1的位数,foo中共有5个1
cout << foo.size() << endl; //8(size函数用来求bitset的大小,一共有8位
cout << foo.test(0) << endl; //true(test函数用来查下标处的元素是0还是1,并返回false或true,此处foo[0]为1,返回true
cout << foo.test(2) << endl; //false(同理,foo[2]为0,返回false
cout << foo.any() << endl; //true(any函数检查bitset中是否有1
cout << foo.none() << endl; //false(none函数检查bitset中是否没有1
cout << foo.all() << endl; //false(all函数检查bitset中是全部为1
test函数参数如果越界会抛出异常
3.bitset支持位操作符
逻辑运算符(且或非),位运算符(异或),函数对象运算(bit_or)
示例
bitset<4> bit1(string("1001"));
bitset<4> bit2(string("0011"));
cout << (bit1 ^= bit2) << endl; // 1010 (bit1对bit2按位异或后赋值给bit1)
cout << (bit1 &= bit2) << endl; // 0010 (按位与后赋值给bit1)
cout << (bit1 |= bit2) << endl; // 0011 (按位或后赋值给bit1)
cout << (bit1 <<= 2) << endl; // 1100 (左移2位,低位补0,有自身赋值)
cout << (bit1 >>= 1) << endl; // 0110 (右移1位,高位补0,有自身赋值)
cout << (~bit2) << endl; // 1100 (按位取反)
cout << (bit2 << 1) << endl; // 0110 (左移,不赋值)
cout << (bit2 >> 1) << endl; // 0001 (右移,不赋值)
cout << (bit1 == bit2) << endl; // false (0110==0011为false)
cout << (bit1 != bit2) << endl; // true (0110!=0011为true)
cout << (bit1 & bit2) << endl; // 0010 (按位与,不赋值)
cout << (bit1 | bit2) << endl; // 0111 (按位或,不赋值)
cout << (bit1 ^ bit2) << endl; // 0101 (按位异或,不赋值)
4.常用修改bitset元素函数
示例
bitset<8> bit3("10011011");
cout << bit3.flip(2) << endl; //10011111 (flip函数传参数时,用于将参数位取反,本行代码将bit3下标2处"反转",即0变1,1变0
cout << bit3.flip() << endl; //01100000 (flip函数不指定参数时,将bitset每一位全部取反
cout << bit3.set() << endl; //11111111 (set函数不指定参数时,将bitset的每一位全部置为1
cout << bit3.set(3, 0) << endl; //11110111 (set函数指定两位参数时,将第一参数位的元素置为第二参数的值,本行对bit3的操作相当于bit3[3]=0
cout << bit3.set(3) << endl; //11111111 (set函数只有一个参数时,将参数下标处置为1
cout << bit3.reset(4) << endl; //11101111 (reset函数传一个参数时将参数下标处置为0
cout << bit3.reset() << endl; //00000000 (reset函数不传参数时将bitset的每一位全部置为0
以上三个函数如果参数越界都会抛出异常
5.类型转换
bitset<8> bit4("10011011");
string s = bit4.to_string(); //将bitset转换成string类型
unsigned long a = bit4.to_ulong(); //将bitset转换成unsigned long类型
unsigned long long b = bit4.to_ullong(); //将bitset转换成unsigned long long类型
cout << s << endl; //10011011
cout << a << endl; //155
cout << b << endl; //155
6.hash
#include <iostream>
#include <bitset>
#include <functional>
int main()
{
std::bitset<4> b1(1);
std::bitset<4> b2(2);
std::bitset<4> b3(2);
std::bitset<4> b4(b2);
std::hash<std::bitset<4>> hash_fn;
//b2,b3,b4的hash值相同
std::cout << hash_fn(b1) << '\n';
std::cout << hash_fn(b2) << '\n';
std::cout << hash_fn(b3) << '\n';
std::cout << hash_fn(b4) << '\n';
return 0;
}
完整示例代码
点击查看代码
#include <bitset>
#include <iostream>
using namespace std;
int main()
{
try
{
bitset<4> b1(123); //十进制123 = 二进制01111011,所以b1是1101(从第0个元素开始算起)
//bitset<4> b2("ss"); //抛出异常
bitset<4> b3(0x4); //16进制4 = 二进制100,b3 = 0010,高位不够用0补齐
bitset<4> b4("11110000"); //只取4位 b4 = 1111
//auto ret1 = b4[55]; //如果越界直接中断
bitset<8> foo("10011011");
cout << foo.count() << endl; //5(count函数用来求bitset中1的位数,foo中共有5个1
cout << foo.size() << endl; //8(size函数用来求bitset的大小,一共有8位
cout << foo.test(0) << endl; //true(test函数用来查下标处的元素是0还是1,并返回false或true,此处foo[0]为1,返回true
cout << foo.test(2) << endl; //false(同理,foo[2]为0,返回false
cout << foo.any() << endl; //true(any函数检查bitset中是否有1
cout << foo.none() << endl; //false(none函数检查bitset中是否没有1
cout << foo.all() << endl; //false(all函数检查bitset中是全部为1
bitset<4> bit1(string("1001"));
bitset<4> bit2(string("0011"));
cout << (bit1 ^= bit2) << endl; // 1010 (bit1对bit2按位异或后赋值给bit1)
cout << (bit1 &= bit2) << endl; // 0010 (按位与后赋值给bit1)
cout << (bit1 |= bit2) << endl; // 0011 (按位或后赋值给bit1)
cout << (bit1 <<= 2) << endl; // 1100 (左移2位,低位补0,有自身赋值)
cout << (bit1 >>= 1) << endl; // 0110 (右移1位,高位补0,有自身赋值)
cout << (~bit2) << endl; // 1100 (按位取反)
cout << (bit2 << 1) << endl; // 0110 (左移,不赋值)
cout << (bit2 >> 1) << endl; // 0001 (右移,不赋值)
cout << (bit1 == bit2) << endl; // false (0110==0011为false)
cout << (bit1 != bit2) << endl; // true (0110!=0011为true)
cout << (bit1 & bit2) << endl; // 0010 (按位与,不赋值)
cout << (bit1 | bit2) << endl; // 0111 (按位或,不赋值)
cout << (bit1 ^ bit2) << endl; // 0101 (按位异或,不赋值)
bitset<8> bit3("10011011");
cout << bit3.flip(2) << endl; //10011111 (flip函数传参数时,用于将参数位取反,本行代码将bit3下标2处"反转",即0变1,1变0
cout << bit3.flip() << endl; //01100000 (flip函数不指定参数时,将bitset每一位全部取反
cout << bit3.set() << endl; //11111111 (set函数不指定参数时,将bitset的每一位全部置为1
cout << bit3.set(3, 0) << endl; //11110111 (set函数指定两位参数时,将第一参数位的元素置为第二参数的值,本行对bit3的操作相当于bit3[3]=0
cout << bit3.set(3) << endl; //11111111 (set函数只有一个参数时,将参数下标处置为1
cout << bit3.reset(4) << endl; //11101111 (reset函数传一个参数时将参数下标处置为0
cout << bit3.reset() << endl; //00000000 (reset函数不传参数时将bitset的每一位全部置为0
bitset<8> bit4("10011011");
string s = bit4.to_string(); //将bitset转换成string类型
unsigned long a = bit4.to_ulong(); //将bitset转换成unsigned long类型
unsigned long long b = bit4.to_ullong(); //将bitset转换成unsigned long long类型
cout << s << endl; //10011011
cout << a << endl; //155
cout << b << endl; //155
int test = 0;
}
catch (...)
{
cout << "error\n";
}
}
二、bitmap
c++没有bitmap,bitmap可以用来处理海量数据。定义一个map,key设置为要存放的元素,value设置为一个bit值。