#pragma once #include #include #include #include #include "BitSet.hpp" namespace Lenyiin { struct HashStr1 { // BKDR size_t operator()(const std::string &str) { size_t hash = 0; for (size_t i = 0; i < str.size(); i++) { hash *= 131; hash += str[i]; } return hash; } }; struct HashStr2 { // SDBM size_t operator()(const std::string &str) { size_t hash = 0; for (size_t i = 0; i < str.size(); i++) { hash *= 65599; hash += str[i]; } return hash; } }; struct HashStr3 { // RS size_t operator()(const std::string &str) { size_t hash = 0; size_t magic = 63689; // 魔数 for (size_t i = 0; i < str.size(); i++) { hash *= magic; hash += str[i]; magic *= 378551; } return hash; } }; // 布隆过滤器底层是个位图 template class BloomFilter { public: BloomFilter(size_t num) : _bs(5 * num), _size(5 * num) { } // 插入元素 void insert(const K &key) { // 将 key 映射到三张位图上 size_t index1 = Hash1()(key) % _size; // Hash1() 是仿函数类型, Hash1()() 是仿函数匿名对象 size_t index2 = Hash2()(key) % _size; size_t index3 = Hash3()(key) % _size; // std::cout << index1 << std::endl; // std::cout << index2 << std::endl; // std::cout << index3 << std::endl; _bs.set(index1); _bs.set(index2); _bs.set(index3); } // 查询元素是否存在 bool contains(const K &key) { size_t index1 = Hash1()(key) % _size; if (_bs.test(index1) == false) { return false; } size_t index2 = Hash2()(key) % _size; if (_bs.test(index2) == false) { return false; } size_t index3 = Hash3()(key) % _size; if (_bs.test(index3) == false) { return false; } return true; // 但是这里也不一定是真的在, 还是可能存在误判 // 判断在, 是不准确的, 可能存在误判, 判断不在是准确的 } // 删除元素 void reset(const K &key) { // 将映射的位置给置零就可以? // 不支持删除, 可能会存在误删。 // 一般布隆过滤器不支持删除操作。 // size_t index1 = Hash1()(key) % _size; // _bs.reset(index1); // size_t index2 = Hash2()(key) % _size; // _bs.reset(index2); // size_t index3 = Hash3()(key) % _size; // _bs.reset(index3); } // 获取位数组的大小 size_t size() const { return _size; } private: BitSet _bs; // 位图 size_t _size; }; }