目录
- 一、位图
 - 1.1位图的概念
 - 1.2位图的实现
 
- 二、布隆过滤器
 - 2.1布隆过滤器的概念
 - 2.2布隆过滤器的实现
 
- 三、位图的扩展--找只出现一次的数
 
一、位图
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;
	};
}
                


















