新闻中心

C++如何实现一个Bloom Filter?C++空间高效的概率数据结构【算法】

2025-12-14
浏览次数:
返回列表
Bloom Filter是一种空间高效的概率型数据结构,用于判断元素“可能在集合中”或“绝对不在”,仅用位数组和多个哈希函数实现,支持add()和contains(),但不支持删除,存在可控误判率。

c++如何实现一个bloom filter?c++空间高效的概率数据结构【算法】

什么是Bloom Filter?为什么用C++实现

Bloom Filter 是一种空间高效的概率型数据结构,用于快速判断一个元素是否“可能在集合中”或“绝对不在集合中”。它不存实际元素,只用少量比特位和多个哈希函数做标记,因此内存占用极小,但存在可控的误判率(false positive),且不支持删除。C++适合实现它,因为能直接控制内存布局、位操作和模板泛型,避免运行时开销。

核心设计:位数组 + 多哈希函数

关键组件只有两个:一个动态位数组(bit array)若干个独立哈希函数。假设位数组长度为 m,插入 n 个元素,用 k 个哈希函数,则最优 k ≈ (m/n) ln2,误判率 ≈ (1 − e−kn/m)k

  • std::vector<uint64_t></uint64_t> 实现位数组,按 64 位整数分块,用位运算(&, |, , )高效读写单个 bit
  • 哈希函数推荐用 std::hash<t></t> 配合不同种子(如乘以质数再异或),或使用 MurmurHash3 的变体,确保分布均匀
  • 对每个元素计算 k 个哈希值,并对 m 取模,得到 k 个位置,全部置为 1

标准接口与关键实现细节

一个实用的 Bloom Filter 类至少应支持 add()contains()size()。注意以下易错点:

  • 位索引计算:哈希值 % m 可能较慢,可用 hash & (m-1) 替代——但要求 m 是 2 的幂,此时需向上取最近的 2 的幂
  • 线程安全:默认不加锁;若需并发写入,可在 add() 中用原子操作(std::atomic_ref<uint64_t></uint64_t>fetch_or)更新对应 word
  • 模板化支持任意类型:通过 std::hash 要求 T 可哈希;对字符串等大对象,可加 move 语义或引用传参减少拷贝
  • 不提供 remove():因为多个元素可能共用同一位,清除会破坏其他元素的存在性

简单可运行示例(无依赖,C++17)

下面是一个轻量级实现的核心骨架(省略异常处理和完整构造逻辑):

美图AI开放平台 美图AI开放平台

美图推出的AI人脸图像处理平台

美图AI开放平台 111 查看详情 美图AI开放平台
template &lt;typename T&gt;
class BloomFilter {
    std::vector&lt;uint64_t&gt; bits;
    size_t m; // total bits
    size_t k; // hash functions count
    std::vector&lt;size_t&gt; seeds = {13, 37, 61, 109, 181}; // example seeds
&lt;pre class=&quot;brush:php;toolbar:false;&quot;&gt;size_t hash(const T&amp; x, size_t seed) const {
    auto h = std::hash&lt;T&gt;{}(x);
    return (h ^ (h &gt;&gt; 32)) * seed;
}

public: BloomFilter(size_t capacity, double false_positive_rate = 0.01) : m{std::max(static_cast(1), static_cast(-capacity log(false_positive_rate) / (log(2)log(2))))}, k{std::max(1UL, static_cast(m / capacity * log(2)))} { m = 1ULL

void add(const T&amp; x) {
    for (size_t i = 0; i &lt; k &amp;&amp; i &lt; seeds.size(); ++i) {
        size_t pos = hash(x, seeds[i]) &amp; (m - 1);
        size_t word_idx = pos / 64;
        size_t bit_idx = pos % 64;
        bits[word_idx] |= (1ULL &lt;&lt; bit_idx);
    }
}

bool contains(const T&amp; x) const {
    for (size_t i = 0; i &lt; k &amp;&amp; i &lt; seeds.size(); ++i) {
        size_t pos = hash(x, seeds[i]) &amp; (m - 1);
        size_t word_idx = pos / 64;
        size_t bit_idx = pos % 64;
        if (!(bits[word_idx] &amp; (1ULL &lt;&lt; bit_idx)))
            return false;
    }
    return true;
}

};

用法:BloomFilter<:string> bf(10000, 0.02); bf.add("hello"); assert(bf.contains("hello")); </:string>

基本上就这些。它不复杂但容易忽略位对齐、哈希分布和误判率估算——调好这三个,就能在缓存穿透防护、URL 去重、数据库布隆索引等场景里稳稳压低内存开销。

以上就是C++如何实现一个Bloom Filter?C++空间高效的概率数据结构【算法】的详细内容,更多请关注其它相关文章!


# 如何用  # 天津网站技术推广  # 重庆网站推广工作室排名  # 绵阳网站建设原创公司  # 辛集网站建设形式  # 凌海装修网站推广  # seo hoo歌手  # 呈贡营销推广  # 怎么做营销组件推广工作  # lama3做seo优化  # 印刷行业推广营销模式  # 多哈  # 游戏开发  # word  # 它不  # 是一种  # 能在  # 多个  # 美图  # 如何实现  # 数据结构  # 为什么  # 质数  # 内存占用  # c++  # ai 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: 零跑汽车11月交付量达70327台 实现连续9个月正增长  Excel文件在线转换快速入口 Excel在线格式转换网站  Shopware订单对象中获取产品自定义字段的正确方法  2306选座时如何选靠窗位置_12306选座靠窗座位查看方法解析  Bing引擎入口最新2025 Bing搜索免费官方登录  Python:递归比较文件夹内容并找出特定类型文件的差异  qq游戏手机版下载安装_qq游戏移动端入口  铁路12306卧铺选择攻略 铁路12306下铺座位预定技巧  J*aScript中在Map循环中检测并处理空数组元素  在Qt QML中通过Python字典动态更新TextEdit内容的教程  拼多多视频播放卡顿如何处理 拼多多视频播放优化技巧  一加Ace 6T支持全新明眸护眼:通过了最严苛的护眼小金标认证  解决macOS上安装pyhdf时‘hdf.h’文件缺失的编译错误  小红书网页版入口链接分享 小红书官网直接进  蛙漫正版漫画平台入口_蛙漫免费阅读全站漫画资源  微信网页版扫码登录入口 微信网页版二维码登录入口  Log4j Console Appender性能瓶颈与高并发优化策略  微信客户端如何收红包_微信客户端接收红包使用教程  PS5 Pro有点优势但不多! 《燕云十六声》PS5平台与PC性能画面对比  顺丰快递查询系统 官方正版查询入口  邮政快递单号查询入口 邮政快递物流信息在线查询入口  解决Rails应用中内容错位与Turbo警告:meta标签误用导致富文本渲染异常  怎样使用“本地安全策略”提升Windows安全性_Secpol.msc配置指南【高手】  Web Components中自定义开关组件状态同步的常见陷阱与解决方案  J*a中实现Go语言select通道多路复用机制  Win10桌面图标出现小盾牌怎么办 Win10去除UAC图标教程【解决】  C++如何实现一个智能指针_手动实现C++ shared_ptr的引用计数功能  qq游戏网页版直接玩_qq游戏免下载快速入口  J*a TimerTask文件监控:HashMap状态管理与常见陷阱规避指南  不同用户不同价格! 索尼开启账户个性化定价测试  微信网页版官方快速登录入口 微信网页版网页版账号直达  斑马英语APP如何开启夜间护眼阅读_斑马英语APP夜间模式与低蓝光设置教程  cad如何更改注释性对象的比例_cad注释性比例调整方法  C++如何操作大型数据集_使用C++流式处理(Streaming)技术避免一次性加载大文件  抖音未来赚钱的新趋势 2025年值得关注的变现风口分析  html怎么在cmd下运行php文件_cmd运行html中php文件方法【教程】  AO3中文官网链接_AO3网页版稳定镜像站  Golang如何优化内存分配与垃圾回收_Golang内存管理与GC优化实践  押井守高度称赞《辐射4》:玩了八年都停不下来!  腾讯视频怎么使用多账号家庭管理_腾讯视频家庭多账号统一管理与权限分配教程  蛙漫限时开放最深处链接_蛙漫全站漫画会员同款秒开地址  马斯克:Optimus 人形机器人复数形式为 Optimi  MinIO大规模对象列表性能瓶颈深度解析与外部元数据管理策略  蛙漫移动版在线看 蛙漫手机浏览器直达入口  sublime如何优雅地处理行尾空格_sublime自动清理多余空白字符配置  《明末:渊虚之羽》设计师谈设计角色:那会刚毕业 充满激情  HTML转PPT成品工具有哪些?HTML网页转PPT成品工具大全  C++的std::forward_list怎么用_C++ STL中单向链表容器的特点与应用  Python大型XML文件高效流式解析教程  Vue.js 图片显示异常排查:理解应用挂载范围与DOM ID唯一性 

搜索