一、位图
1、概念
位图,就是用每一位(bit)来存放某种状态,适用于海量数据,数据无重复的场景。通常是用来判断某个数据存不存在的。
如:数据是否在给定的整形数据中,结果是在或者不在,刚好是两种状态,那么可以使用一个二进制比特位来代表数据是否存在的信息,如果二进制比特位为1,代表存在,为0代表不存在。我们将每一个数据都以某种方式映射到位图中,那么一个位置就代表了其所对应的数据,一个数据只映射到其对应的位置中(一一对应)。
应用
- 快速查找某个数据是否在一个集合中
- 排序
- 求两个集合的交集、并集等
- 操作系统中磁盘块标记
2、模拟实现
#include<vector>namespace bitset
{template<size_t N>class bitset{public:bitset(){_bs.resize(N);}void set(size_t key){size_t i = key / 32; //找到存储的int块size_t j = key % 32; //找到该块内存储的位置_bs[i] |= (1 << j);}void reset(size_t key){size_t i = key / 32; //找到存储的int块size_t j = key % 32; //找到该块内存储的位置_bs[i] &= ~(1 << j);}bool test(size_t key){size_t i = key / 32; //找到存储的int块size_t j = key % 32; //找到该块内存储的位置return _bs[i] &= (1 << j);}private:vector<int> _bs;};
}
二、布隆过滤器
1、概念
布隆过滤器是由布隆(Burton Howard Bloom)在1970年提出的 一种紧凑型的、比较巧妙的概率型数据结构,特点是高效地插入和查询,可以用来告诉你 “某样东西一定不存在或者可能存在”,它是用多个哈希函数,将一个数据映射到位图结构中。此种方式不仅可以提升查询效率,也可以节省大量的内存空间。
注:布隆过滤器如果说某个元素不存在时,该元素一定不存在,如果该元素存在时,该元素可能存在,因为有些哈希函数存在一定的误判。
2、模拟实现
#include"bitset.h"
#include<string>struct BKDRHash
{size_t operator()(const string& key){// BKDRsize_t hash = 0;for (auto e : key){hash *= 31;hash += e;}return hash;}
};struct APHash
{size_t operator()(const string& key){size_t hash = 0;for (size_t i = 0; i < key.size(); i++){char ch = key[i];if ((i & 1) == 0){hash ^= ((hash << 7) ^ ch ^ (hash >> 3));}else{hash ^= (~((hash << 11) ^ ch ^ (hash >> 5)));}}return hash;}
};struct DJBHash
{size_t operator()(const string& key){size_t hash = 5381;for (auto ch : key){hash += (hash << 5) + ch;}return hash;}
};template<size_t N, class K = string, class HashF1 = BKDRHash, class HashF2 = APHash, class HashF3 = DJBHash>
class BloomFilter
{typedef bitset::bitset<N> bitset;
public:void set(const K& key){size_t hashi1 = HashF1()(key) % N;_bs.set(hashi1);size_t hashi2 = HashF2()(key) % N;_bs.set(hashi2);size_t hashi3 = HashF3()(key) % N;_bs.set(hashi3);}bool test(const K& key){size_t hashi1 = HashF1()(key) % N;if (!_bs.test(hashi1))return false;size_t hashi2 = HashF2()(key) % N;if (!_bs.test(hashi2))return false;size_t hashi3 = HashF3()(key) % N;if (!_bs.test(hashi3))return false;return true;}private:bitset _bs;
};