目录
- 一、位图
- 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;
};
}