例子:如下图
namespace Ding
{templateclass bitset{public:bitset(){_bits.resize(N / 8 + 1, 0);}// 将x比特位置1void set(size_t x){size_t i = x / 8;size_t j = x % 8;_bits[i] |= (1 << j);}// 将x比特位0void reset(size_t x){size_t i = x / 8;size_t j = x % 8;_bits[i] &= ~(1 << j);}// 检测位图中x是否为1bool test(size_t x){size_t i = x / 8;size_t j = x % 8;return _bits[i] & (1 << j);}private:vector _bits;};void test_bit_set1(){bitset<100> bs1;bs1.set(8);bs1.set(9);bs1.set(20);cout << bs1.test(8) << endl;cout << bs1.test(9) << endl;cout << bs1.test(20) << endl;bs1.reset(8);bs1.reset(9);bs1.reset(20);cout << bs1.test(8) << endl;cout << bs1.test(9) << endl;cout << bs1.test(20) << endl;}
}
一个位图一般标记一个数在和不在;数据太大状态多;我们可以用两个位图来标记。
例如:00:未出现;01:表示出现一次;10:表示出现二次;11:表示出现3次及以上。两个位图分别取其中一个bit位来表示即可。
namespace Ding
{templateclass twobitset{public:void set(size_t x){bool inset1 = _bs1.test(x);bool inset2 = _bs2.test(x);if (inset1 == false && inset2 == false){//->01_bs2.set(x);}else if (inset1 == false && inset2 == true){//->10_bs1.set(x);_bs2.reset(x);}else if (inset1 == true && inset2 == false){//->11_bs2.set(x);}}void print_once_num(){for (size_t i = 0; i < N; ++i){if (_bs1.test(i) == false && _bs2.test(i) == true) //01{cout << i << endl;}}}private:bitset _bs1;bitset _bs2;};void test_bit_set3(){int a[] = { 3, 4, 5, 2, 3, 4, 4, 4, 4, 12, 77, 65, 44, 4, 44, 99, 33, 33, 33, 6, 5, 34, 12 };twobitset<100> bs;for (auto e : a){bs.set(e);}bs.print_once_num();cout << endl << endl;sort(a, a + sizeof(a) / sizeof(a[0]));for (auto e : a){cout << e << " ";}cout << endl;}
}