位图实现原理、模拟及库函数中bitset

位图,就是用每一个比特位来表示某种状态,来判断数据存在与否。

如:

位图实现原理、模拟及库函数中bitset_第1张图片
位图的优点: 节省空间,效率高
位图的缺点: 只能处理整形

 
 

1.实现bitset

类模型:

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.1 设置比特位

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);
	}

1.2 重置比特位

	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,其余不变,则要将原数据取反,再与即可
	}

1.3 检测比特位

	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;
}

位图实现原理、模拟及库函数中bitset_第2张图片

2.C++库函数中bitset

2.1 构造

  1. 值构造:构造时,可采用整数值构造,此时按照数据的二进制比特位,对bitset中对应的比特位置1;

代码:

int main()
{
     
	bitset<15> bt(10);
	// 1010
	cout << bt << endl;
	return 0;
}

结果:

位图实现原理、模拟及库函数中bitset_第3张图片
注意:当不足bitset位数时,高位补0,超出时,数据截断。
位图实现原理、模拟及库函数中bitset_第4张图片

  1. 字符串构造:和值构造同理,当不足bitset位数时,高位补0,超出时,数据截断。右边为低位,左边为高位。

例:

位图实现原理、模拟及库函数中bitset_第5张图片

2.2 operator[]

函数原型:
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;
}

2.3 count

函数原型:
size_t count() const noexcept;
返回值:返回位图中1的个数

例:

位图实现原理、模拟及库函数中bitset_第6张图片

2.4 size

函数原型:
constexpr size_t size() noexcept;
返回值:返回位图的位数

例:

位图实现原理、模拟及库函数中bitset_第7张图片

2.5 test

函数原型:
bool test (size_t pos) const;
返回值:返回pos位置,数据是否存在

例:

位图实现原理、模拟及库函数中bitset_第8张图片

2.6 any

函数原型:
bool any() const noexcept;
返回值:若位图中有1的个数大于等于1,则返回真,1的个数为0,返回假

例:

位图实现原理、模拟及库函数中bitset_第9张图片

2.7 none

函数原型:
bool none() const noexcept;
返回值:若位图中没有1,则返回真,若有1,则返回假

例:

位图实现原理、模拟及库函数中bitset_第10张图片

2.8 all

函数原型:
bool all() const noexcept;
返回值:若位图中全为1,返回真,否则返回假

例:

位图实现原理、模拟及库函数中bitset_第11张图片

2.9 set

函数原型:
bitset& set() noexcept; //将所有比特位全部置为1
bitset& set (size_t pos, bool val = true);//将pos比特位置为0或者1,默认为1
注意:若pos大于位图位数,则会抛异常,out_of_range

例:

位图实现原理、模拟及库函数中bitset_第12张图片

位图实现原理、模拟及库函数中bitset_第13张图片

2.10 reset

函数原型:
bitset& reset() noexcept; //将所有比特位置为0
bitset& reset (size_t pos); //将pos位置置为0
注意:若pos大于位图位数,则会抛异常,out_of_range

例:

位图实现原理、模拟及库函数中bitset_第14张图片

2.11 filp

函数原型:
bitset& flip() noexcept; //全部比特位翻转,0->1,1->0
bitset& flip (size_t pos); pos比特位翻转,0->1,1->0
注意:若pos大于位图位数,则会抛异常,out_of_range

例:

位图实现原理、模拟及库函数中bitset_第15张图片

你可能感兴趣的