【位图+布隆过滤器】

一、位图

1.1位图的概念

所谓位图,就是用每一位来存放某种状态,适用于海量数据,数据无重复的场景。通常是用来判断某个数据存不存在的。

1.2位图的实现

位图实现的思想:
在这里插入图片描述
位图实现的代码:

#pragma once
#include<iostream>
using namespace std;
#include<vector>

namespace Ting
{
	template<size_t N>
	class bitset
	{
	public:
		bitset()
		{
			_v.resize(N / 32 + 1);
		}
		void set(const size_t& x)
		{
			int i = x / 32;
			int j = x % 32;

			_v[i] = _v[i] | (1 << j);
		}

		void reset(const size_t& x)
		{
			int i = x / 32;
			int j = x % 32;

			_v[i] &= ~(1 << j);
		}

		bool test(const size_t& x)
		{
			int i = x / 32;
			int j = x % 32;

			return _v[i] & (1 << j);
		}
	private:
		vector<int> _v;
	};
}

二、布隆过滤器

2.1布隆过滤器的概念

布隆过滤器是由布隆(Burton Howard Bloom)在1970年提出的 一种紧凑型的、比较巧妙的概率型数据结构,特点是高效地插入和查询,可以用来告诉你 “某样东西一定不存在或者可能存在”,它是用多个哈希函数,将一个数据映射到位图结构中。此种方式不仅可以提升查询效率,也可以节省大量的内存空间。
在这里插入图片描述

2.2布隆过滤器的实现

#pragma once
#include"bitset.h"
namespace Ting
{
	struct BKDRHash
	{
		size_t operator()(const string& s)
		{
			size_t value = 0;
			for (auto ch : s)
			{
				value *= 31;
				value += ch;
			}
			return value;
		}
	};
	struct APHash
	{
		size_t operator()(const string& s)
		{
			size_t hash = 0;
			for (long i = 0; i < s.size(); i++)
			{
				if ((i & 1) == 0)
				{
					hash ^= ((hash << 7) ^ s[i] ^ (hash >> 3));
				}
				else
				{
					hash ^= (~((hash << 11) ^ s[i] ^ (hash >> 5)));
				}
			}
			return hash;
		}
	};
	struct DJBHash
	{
		size_t operator()(const string& s)
		{
			size_t hash = 5381;
			for (auto ch : s)
			{
				hash += (hash << 5) + ch;
			}
			return hash;
		}
	};


	template<size_t N,
	         size_t X=5,
		     class K=string,
	         class HashFunc1= BKDRHash,
	         class HashFunc2= APHash,
		     class HashFunc3= DJBHash>
	class bloomfilter
	{
	public:
		void set(const K& key)
		{
			HashFunc1 hf1;
			HashFunc2 hf2;
			HashFunc3 hf3;

			int len = X * N;
			int index1 = hf1(key)% len;
			int index2 = hf2(key)% len;
			int index3 = hf3(key)% len;

			_bt.set(index1);
			_bt.set(index2);
			_bt.set(index3);
		}

		bool test(const K& key)
		{
			HashFunc1 hf1;
			HashFunc2 hf2;
			HashFunc3 hf3;

			int len = X * N;
			int index1 = hf1(key) % len;
			if (_bt.test(index1) == false)
				return false;

			int index2 = hf2(key) % len;
			if (_bt.test(index2) == false)
				return false;

			int index3 = hf3(key) % len;
			if (_bt.test(index3) == false)
				return false;

			return true;

		}
	private:
		Ting::bitset<N* X> _bt;
	};

三、位图的扩展–找只出现一次的数

//找只出现一次的数
	template<size_t N>
	class onlyone
	{
	public:
		void set(const int& x)
		{
			//00->01
			if (!_bt1.test(x)&&!_bt2.test(x))
			{
				_bt2.set(x);
				return;
			}

			//01->11
			if (!_bt1.test(x) && _bt2.test(x))
			{
				_bt1.set(x);
			}
		}

		bool test(const int& x)
		{
			if (!_bt1.test(x) && _bt2.test(x))
			{
				return true;
			}

			return false;
		}
	private:
		Ting::bitset<N> _bt1;
		Ting::bitset<N> _bt2;

	};
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值