位图,就是用每一个比特位来表示某种状态,来判断数据存在与否。
如:
类模型:
class BitSet
{
public:
BitSet(size_t n = 31) //n为有多少比特位数
:_v((n >> 5) + 1) //+1是为了避免比特位数小于32时,无法开辟出空间
,_bitCount(n)
{
}
private:
vector<int> _v;//底层存储使用的是vector
size_t _bitCount;//比特位的位数
};
1 << bitpos
是将该bitpos位置置为1,则进行或操作即可将位图中置为1
void Set(size_t pos, bool val = true)//将pos比特位置为1
{
if (pos >= _bitCount)//pos位置应该小于比特位数,否则超出了范围
{
cout << "out_of_range" << endl;
return;
}
if (val)//默认情况下,Set是将pos位置置为1
{
size_t index = (pos >> 5);//在第多少个int里面
size_t bitpos = pos % 32;//在该int中的比特位位置
_v[index] |= (1 << bitpos);
}
else//val = false时,调用Reset
ReSet(pos);
}
void ReSet(size_t pos)//将pos位置为0
{
if (pos >= _bitCount)//pos位置应该小于比特位数,否则超出了范围
{
cout << "out_of_range" << endl;
return;
}
size_t index = (pos >> 5);//在第多少个整形里面
size_t bitpos = pos % 32;//将该位置置为0
_v[index] &= ~(1 << bitpos);//只将一个位置置为0,其余不变,则要将原数据取反,再与即可
}
bool Test(size_t pos)
{
if (pos >= _bitCount)//pos位置应该小于比特位数,否则超出了范围
{
cout << "out_of_range" << endl;
return false;
}
size_t index = (pos >> 5);//在第多少个整形里面
size_t bitpos = pos % 32;//位置
return _v[index] & (1 << bitpos);
}
完整代码:
class BitSet
{
public:
BitSet(size_t n = 10)//n为比特位数
:_v((n >> 5) + 1)
,_bitCount(n)
{
}
void Set(size_t pos, bool val = true)//将pos比特位置为1
{
if (pos >= _bitCount)
{
cout << "out_of_range" << endl;
return;
}
if (val)
{
size_t index = (pos >> 5);//在第多少个整形里面
size_t bitpos = pos % 32;//将该位置置为1
_v[index] |= (1 << bitpos);
}
else
ReSet(pos);
}
void ReSet(size_t pos)
{
if (pos >= _bitCount)
{
cout << "out_of_range" << endl;
return;
}
size_t index = (pos >> 5);//在第多少个整形里面
size_t bitpos = pos % 32;//将该位置置为0
_v[index] &= ~(1 << bitpos);
}
bool Test(size_t pos)
{
if (pos >= _bitCount)
{
cout << "out_of_range" << endl;
return false;
}
size_t index = (pos >> 5);//在第多少个整形里面
size_t bitpos = pos % 32;//位置
return _v[index] & (1 << bitpos);
}
private:
vector<int> _v;
size_t _bitCount;
};
测试代码:
int main()
{
BitSet bt(100);//100个比特位
bt.Set(10);//第10个比特位置为1
bt.Set(98);//第98个比特位置为1
bt.Set(12);//第12个比特位置为1
cout << bt.Test(10) << endl;//查看第10个比特位是否为1
bt.ReSet(12);//第12个比特位置为1
cout << bt.Test(12) << endl;//查看第12个比特位是否为0
bt.Set(98, 0);//第98个比特位置为0
cout << bt.Test(98) << endl;//查看第98个比特位是否为0
return 0;
}
代码:
int main()
{
bitset<15> bt(10);
// 1010
cout << bt << endl;
return 0;
}
结果:
注意:当不足bitset位数时,高位补0,超出时,数据截断。
例:
函数原型:
bool operator[] (size_t pos) const; //const对象,返回bool值,表示该位是否存在
reference operator[] (size_t pos); //返回值,并且可对该值操作
注意:若pos 不要大于 位图的位数。
例:
int main()
{
bitset<15> bt(string("010101"));
cout << bt << endl;
cout << bt[0] << endl;
return 0;
}
函数原型:
size_t count() const noexcept;
返回值:返回位图中1的个数
例:
函数原型:
constexpr size_t size() noexcept;
返回值:返回位图的位数
例:
函数原型:
bool test (size_t pos) const;
返回值:返回pos位置,数据是否存在
例:
函数原型:
bool any() const noexcept;
返回值:若位图中有1的个数大于等于1,则返回真,1的个数为0,返回假
例:
函数原型:
bool none() const noexcept;
返回值:若位图中没有1,则返回真,若有1,则返回假
例:
函数原型:
bool all() const noexcept;
返回值:若位图中全为1,返回真,否则返回假
例:
函数原型:
bitset& set() noexcept; //将所有比特位全部置为1
bitset& set (size_t pos, bool val = true);//将pos比特位置为0或者1,默认为1
注意:若pos大于位图位数,则会抛异常,out_of_range
例:
函数原型:
bitset& reset() noexcept; //将所有比特位置为0
bitset& reset (size_t pos); //将pos位置置为0
注意:若pos大于位图位数,则会抛异常,out_of_range
例:
函数原型:
bitset& flip() noexcept; //全部比特位翻转,0->1,1->0
bitset& flip (size_t pos); pos比特位翻转,0->1,1->0
注意:若pos大于位图位数,则会抛异常,out_of_range
例: