目录
一、bitset接口介绍
二、bitset的实现
1. 构造函数
2. 设置位(set)
3. 清空位(reset)
4. 获取位的状态(test)
三、源代码
一、bitset接口介绍
#include <iostream>
#include <vector>
using namespace std;
namespace mlg
{
template<size_t N>
class bitset
{
public:
//构造函数
bitset(){}
//设置位
void set(size_t x){}
//清空位
void reset(size_t x){}
//获取位的状态
bool test(size_t x){}
private:
std::vector<char> _bits;//位图
};
}
bitset的实现,实现出以上的几个接口就可以了
二、bitset的实现
1. 构造函数
我们用vector来作为容器,存储char, 对应8个bit,我们利用非类型的模板参数,来指定开多少个比特位,如:N是开100个比特位,那么实际上我们这个vector要开多大呢?肯定不能直接开100,我们需要对N / 8 + 1;因为N不一定是8的整数倍;100 / 8 = 12(实际开了96个比特位),没有达到我们的要求;
bitset()
{
_bits.resize(N / 8 + 1, 0);
}
2. 设置位(set)
我们要将某个位设置为1,我们的操作是先将x除8,得到vector中的第几个位图(也就是第几个char),然后再 x % 8得到当前位图的第几位;如何将这个位置设置为1,但不影响其他位呢?将1左移 j 位后与第 i 个整数进行或运算即可
void set(size_t x)
{
size_t i = x / 8;
size_t j = x % 8;
_bits[i] |= (1 << j);
}
3. 清空位(reset)
清空位图中指定的位的方法如下:
- 计算出该位位于第 i 个位图的第 j 个比特位。
- 将1左移 j 位再整体反转后与第 i 个整数进行与运算即可。
void reset(size_t x)
{
size_t i = x / 8;
size_t j = x % 8;
_bits[i] &= (~(1 << j));
}
4. 获取位的状态(test)
获取位图中指定的位的状态的方法如下:
- 计算出该位位于第 i 个位图的第 j 个比特位。
- 将1左移 j 位后与第 i 个整数进行与运算得出结果。
- 若结果非0,则该位被设置,否则该位未被设置。
bool test(size_t x)
{
size_t i = x / 8;
size_t j = x % 8;
return _bits[i] & (1 << j);
}
三、源代码
#include <iostream>
#include <vector>
using namespace std;
namespace mlg
{
template<size_t N>
class bitset
{
public:
//构造函数
bitset()
{
_bits.resize(N / 8 + 1, 0);
}
//设置位
void set(size_t x)
{
size_t i = x / 8;
size_t j = x % 8;
_bits[i] |= (1 << j);
}
//清空位
void reset(size_t x)
{
size_t i = x / 8;
size_t j = x % 8;
_bits[i] &= (~(1 << j));
}
//获取位的状态
bool test(size_t x)
{
size_t i = x / 8;
size_t j = x % 8;
return _bits[i] & (1 << j);
}
private:
std::vector<char> _bits;//位图
};
void test_bitset()
{
bitset<100> bs;
bs.set(5);
bs.set(4);
bs.set(10);
bs.set(20);
cout << bs.test(5) << endl;
cout << bs.test(4) << endl;
cout << bs.test(10) << endl;
cout << bs.test(20) << endl;
cout << bs.test(21) << endl;
cout << bs.test(6) << endl << endl;
bs.reset(20);
bs.reset(10);
bs.reset(5);
cout << bs.test(5) << endl;
cout << bs.test(4) << endl;
cout << bs.test(10) << endl;
cout << bs.test(20) << endl;
cout << bs.test(21) << endl;
cout << bs.test(6) << endl;
}
}