• 【C++布隆过滤器和哈希切分】


    目录

    1.布隆过滤器概念

    2.布隆过滤器优点

    3.哈希切分


     

    位图储存的类型只能是整形,有没有储存自定义类型或者是字符串类型的“位图”呢?

    1.布隆过滤器概念

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

    简单一点的说就是:把字符串转化为整形存储在位图中,当时转化后的整形会和数组的比特位数量取模,取模的结果可能相同然后互相影响,那我们可以映射多个位置,来减少冲突的概率

    1. //不同的字符串用得到整形不一样
    2. struct BKDRHash
    3. {
    4. size_t operator()(const string& s)
    5. {
    6. // BKDR
    7. size_t value = 0;
    8. for (auto ch : s)
    9. {
    10. value *= 31;
    11. value += ch;
    12. }
    13. return value;
    14. }
    15. };
    16. struct APHash
    17. {
    18. size_t operator()(const string& s)
    19. {
    20. size_t hash = 0;
    21. for (long i = 0; i < s.size(); i++)
    22. {
    23. if ((i & 1) == 0)
    24. {
    25. hash ^= ((hash << 7) ^ s[i] ^ (hash >> 3));
    26. }
    27. else
    28. {
    29. hash ^= (~((hash << 11) ^ s[i] ^ (hash >> 5)));
    30. }
    31. }
    32. return hash;
    33. }
    34. };
    35. struct DJBHash
    36. {
    37. size_t operator()(const string& s)
    38. {
    39. size_t hash = 5381;
    40. for (auto ch : s)
    41. {
    42. hash += (hash << 5) + ch;
    43. }
    44. return hash;
    45. }
    46. };
    47. template<size_t N,
    48. size_t X = 8,
    49. class K = string,
    50. class HashFunc1 = BKDRHash,
    51. class HashFunc2 = APHash,
    52. class HashFunc3 = DJBHash>
    53. //x=8,char有8个比特位,N是char的数量
    54. class BloomFilter
    55. {
    56. public:
    57. //映射3个位置
    58. void Set(const K& key)
    59. {
    60. size_t len = X * N;
    61. size_t index1 = HashFunc1()(key) % len;
    62. size_t index2 = HashFunc2()(key) % len;
    63. size_t index3 = HashFunc3()(key) % len;
    64. _bs.set(index1);
    65. _bs.set(index2);
    66. _bs.set(index3);
    67. }
    68. //映射3个位置,有一个位置不在说明就不在,如果都在也有可能是误判
    69. bool Test(const K& key)
    70. {
    71. size_t len = X * N;
    72. size_t index1 = HashFunc1()(key) % len;
    73. if (_bs.test(index1) == false)
    74. return false;
    75. size_t index2 = HashFunc2()(key) % len;
    76. if (_bs.test(index2) == false)
    77. return false;
    78. size_t index3 = HashFunc3()(key) % len;
    79. if (_bs.test(index3) == false)
    80. return false;
    81. return true; // 存在误判的
    82. }
    83. // 不支持删除,删除可能会影响其他值。
    84. void Reset(const K& key);
    85. private:
    86. bitset _bs;
    87. };

    为什么布隆过滤器的特性: 某一个元素一定不存在或者可能存在

     

    当插入元素和过滤器长度的比例越大于下面公式的结果,越误判率会小;但是开太多浪费,比例+1就好

    • 例如:插入元素个数是100;那么过滤器的长度开500;当时开空间的类型是char(字节),所以传模板参数应该/8,为50;BloomFilter<50> bft;

    2.布隆过滤器优点

    1. 增加和查询元素的时间复杂度为:O(K), (K为哈希函数的个数,一般比较小),与数据量大小无关
    2. 布隆过滤器不需要存储元素本身,在某些对保密要求比较严格的场合有很大优势
    3. 在能够承受一定的误判时,布隆过滤器比其他数据结构有这很大的空间优势
    4. 数据量很大时,布隆过滤器可以表示全集,其他数据结构不能

    布隆过滤器缺陷

    1. 有误判率,即存在假阳性(False Position),即不能准确判断元素是否在集合中(补救方法:再建立一个白 名单,存储可能会误判的数据)
    2. 不能获取元素本身
    3. 一般情况下不能从布隆过滤器中删除元素

    问题:给两个文件,分别有100亿个query,我们只有1G内存,如何找到两个文件交集?分别给出精确算法近似算法

    3.哈希切分

    • 先算出文件大小,好切成多份准确数目的小文件
    • 同一个元素映射的小文件的编号一定相同

     

  • 相关阅读:
    观察者模式与发布订阅者模式
    接口自动化测试实践指导(下):接口自动化测试断言设置思路
    图论例题解析
    【JAVA版本】websocket获取B站直播弹幕——基于直播开放平台
    [洛谷] 求第 k 小的数 [ P1923 ]
    【LIN总线测试】——LIN主节点网络管理测试
    【python 小白到精通】第五章:面向对象编程 - 三星运行模拟
    Puppeteer实战指南:自动化抓取网页中的图片资源
    基于Android的仓库管理系统APP设计与实现
    MongoDB介绍和基本使用
  • 原文地址:https://blog.csdn.net/m0_72964546/article/details/127892645