1.函数接口
包含以下接口
构造 | |
---|---|
std::bitset<8> foo; | 构造一个8位的bitset |
std::bitset<100> foo(int a); | 将a转为2进制并放入一个长为100位的bitset中 |
函数 | 功能 |
---|---|
bool all() const noexcept; | 判断bitset中所有位是否都已设置(为1)。 |
bool any() const; | bitset中是否存在值为1 |
size_t count() const; | 计算比特位为1的位数 |
bitset& flip(); | 全部位逐位取反,即所有的1变为0,0变为1 |
bitset& flip (size_t pos); | pos位取反 |
bool none() const; | 是否不存在值为1 |
bool operator[] (size_t pos) const; | 支持[ ]访问第pos位 |
bitset& reset(); | 全部位重置为0 |
bitset& reset (size_t pos); | pos位置为0 |
bitset& set(); | 无参;默认全部位置为1 |
bitset& set (size_t pos, bool val = true); | 带参;将pos位置为0(val=false)或1,默认置为1 |
size_t size() const; | bitset的位长 |
bool test (size_t pos) const; | 测试pos位是否为1 |
to_string() | 将二进制转换为字符串输出 |
to_ullong() const; | 将二进制比特位转换为unsigned long long输出 |
to_ulong() const; | 将二进制比特位转换为unsigned long输出 |
此外bitset也支持位操作:& | ^ << >> ~
位图的应用:
快速查找个数据是否在一个集合中--->布隆过滤器
排序
求两个集合的交并集、并集等。
操作系统中磁盘块标记
部分功能模拟实现:
这里是简化了vc6.0中的PJ版本代码
部分参数说明:
_N :bit位数
_Nb : 即32个比特位
_Ty _A[_Nw + 1] :为底层存放bit位的数组,其中_Nw+1为需要开辟的vector大小。
_P : 第pos位
namespace bit
{
template<size_t _N>
class bitset
{
public:
typedef unsigned long _Ty;
public:
bitset()
{
_Tidy();
}
public:
bitset<_N>& set()
{
_Tidy(~(_Ty)0);
return (*this);
}
bitset<_N>& set(size_t _P, bool _X = true)
{
if (_X)
_A[_P / _Nb] |= (_Ty)1 << _P % _Nb;
else
_A[_P / _Nb] &= ~((_Ty)1 << _P % _Nb);
return (*this);
}
size_t size() const
{
return (_N);
}
bool test(size_t _P) const
{
return ((_A[_P / _Nb] & ((_Ty)1 << _P % _Nb)) != 0);
}
bool any() const
{
for (int _I = _Nw; 0 <= _I; --_I)
if (_A[_I] != 0)
return (true);
return (false);
}
bool none() const
{
return (!any());
}
size_t count() const
{
size_t _V = 0;
for (int _I = _Nw; 0 <= _I; --_I)
for (_Ty _X = _A[_I]; _X != 0; _X >>= 4)
_V += "\0\1\1\2\1\2\2\3"
"\1\2\2\3\2\3\3\4"[_X & 0xF]; //这里逐个计算每四个字节中1的个数相加
return (_V);
}
class reference //引用类
{
friend class bitset<_N>;
public:
reference& operator=(bool _X)
{
_Pbs->set(_Off, _X);
return (*this);
}
reference& operator=(const reference& _Bs)
{
_Pbs->set(_Off, bool(_Bs));
return (*this);
}
reference& flip()
{
_Pbs->flip(_Off);
return (*this);
}
bool operator~() const
{
return (!_Pbs->test(_Off));
}
operator bool() const
{
return (_Pbs->test(_Off));
}
private:
reference(bitset<_N>& _X, size_t _P)
: _Pbs(&_X), _Off(_P) {}
bitset<_N>* _Pbs;
size_t _Off;
};
reference operator[](size_t _P)
{
return (reference(*this, _P));
}
private:
void _Tidy(_Ty _X = 0)
{
for (int _I = _Nw; 0 <= _I; --_I)
_A[_I] = _X;
if (_X != 0)
_Trim();
}
void _Trim() //裁剪
{
if (_N % _Nb != 0)
_A[_Nw] &= ((_Ty)1 << _N % _Nb) - 1;
}
private:
enum
{
//#define CHAR_BIT 8
_Nb = CHAR_BIT * sizeof(_Ty), //_Nb 即32比特位
_Nw = _N == 0 ? 0 : (_N - 1) / _Nb
};
_Ty _A[_Nw + 1]; //_A为底层存放bit位的数组,其中_Nw+1为需要开辟的vector大小。
private:
friend ostream& operator<<(ostream& _O, const bitset<_N>& _R)
{
for (size_t _P = _N; 0 < _P;)
_O << (_R.test(--_P) ? '1' : '0');
return (_O);
}
};
};
void main()
{
bit::bitset<20> bt;
cout << "bt = " << bt << endl;
//bt.set(3);
bt[3] = 1;
cout << "bt = " << bt << endl;
cout << "count = " << bt.count() << endl;
}