C++位图

位图一般用于需要对大量数据记录其状态。比如,存在或不存在,通过0或1也可以用多个位图记录多种状态,如 01,10,00,11(在两个位图下,可以记录4种状态,当然也可以横向记录,比如将某个位图的4个位记录状态,这样可以最多记录16种状态)

位图的关键就是0和1之间的改变,并且不影响其他位的数值。

namespace GuYu
{

	class bitset
	{
	public:
		bitset()
			:_num(0)
		{ }

		void set(size_t n)
		{
			if (n / 32 + 1 > _v.size())
			{
				_v.resize(n / 32 + 1, 0);
			}
			size_t Index = n / 32;
			size_t Pos = n % 32;
			_v[Index] = _v[Index] | (1 << Pos);
		}


		void reset(size_t n)
		{
			size_t Index = n / 32;
			size_t Pos = n % 32;
			_v[Index] = _v[Index] &(~(1 << Pos));  //  1000000->0111111
			// _v[Index]=(_v[Index]|(1<<Pos))^(1<<Pos)
		}


		bool test(size_t x)
		{
			size_t Index = x / 32;
			size_t Pos = x % 32;
			int num = (_v[Index] & (1 << Pos)) >> Pos;
			if (num == 1)
			{
				return true;
			}
			return false;
		}


	private:
		vector<int> _v;
		size_t _num;
	};
}

Bloom_Filter布隆过滤器

Bloom_Filter实际是为了解决不同的非size_t的数据通过哈希算法映射到同一位置引发的哈希冲突。

通过不同的方式将(拿string举例)string映射到多个位置(多个位置的位设为1),布隆过滤器不支持删改,当某个位被多个值映射了,删除会影响其他值的检查。

struct hash1str
{
	size_t operator()(const string& key)
	{
		size_t num = 0;
		for (int i = 0; i < key.size(); i++)
		{
			num += key[i];
		}
		return num;
	}
};
struct hash2str
{
	size_t operator()(const string& key)
	{
		size_t num = 0;
		for (int i = 0; i < key.size(); i++)
		{
			num *= 31;
			num += key[i];
		}
		return num;
	}
};
struct hash3str
{
	size_t operator()(const string& key)
	{
		size_t num = 0;
		for (int i = 0; i < key.size(); i++)
		{
			num *= 11;
			num += key[i];
		}
		return num;
	}
};


template<class K=string,class hash1=hash1str,class hash2=hash2str,class hash3=hash3str>
class BloomFilter
{
public:
	void set(const K& key)
	{
		//  通过不同的哈希计算方式,使key不同,映射到不同的位置
		size_t index1 = hash1()(key);
		size_t index2 = hash2()(key);
		size_t index3 = hash3()(key);
		//  对_bf的这三个位置修改
		_bf.set(index1);
		_bf.set(index2);
		_bf.set(index3);
	}


	bool test(const K& key)
	{
		size_t index1 = hash1()(key);
		if (_bf.test(index1) == false)
		{
			return false;
		}
		size_t index2 = hash2()(key);
		if (_bf.test(index2) == false)
		{
			return false;
		}
		size_t index3 = hash3()(key);
		if (_bf.test(index3) == false)
		{
			return false;
		}
		return true;
	}


private:
	bitset _bf;
};

如何优化布隆过滤器,使其支持删除操作?

将位改为计数器,vector<unsigned char> vc,当映射到了vc[index],v[index]++ (v[index<255)。

 // 添加元素
    void add(const string& item) {
        for (size_t i = 0; i < hash_count; ++i) {
            size_t index = hash(item, i);
            if (counters[index] < 255) {  // 防止计数器溢出
                ++counters[index];
            }
        }
    }
    
    // 删除元素
    void remove(const string& item) {
        for (size_t i = 0; i < hash_count; ++i) {
            size_t index = hash(item, i);
            if (counters[index] > 0) {
                --counters[index];
            }
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值