全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

c++如何实现一个Bloom Filter c++布隆过滤器算法【实例】

布隆过滤器用位数组+多哈希实现概率判断:先计算最优位数组大小m和哈希个数k,再通过扰动哈希(如std::hash加种子)生成k个索引,插入设位、查询验位,支持高速去重与缓存防护。

用 C++ 实现一个布隆过滤器,核心是:一个位数组(std::vectorstd::bitset) + 多个独立哈希函数 + 插入/查询逻辑。它不存原始数据,只通过概率方式判断“可能在集合中”或“一定不在”,适合高速去重、缓存穿透防护等场景。

关键设计要点

布隆过滤器不是万能的,实现前需明确三点:

  • 预期元素数量 n:影响位数组大小
  • 可接受的误判率 ε(如 0.01 表示 1%):决定最优哈希函数个数 k 和位数组长度 m
  • 哈希函数必须均匀、独立、快速:推荐用 MurmurHash3 的变体,或基于 std::hash 组合多个种子

位数组与容量计算

位数组大小 m 和哈希函数个数 k 有理论公式:

m = −(n × ln ε) / (ln 2)²k = (m / n) × ln 2

实际中可简化为:

  • n = 100000,目标误判率 ε = 0.01 → 计算得 m ≈ 958506 位(约 117 KB),k = 7
  • C++ 中建议用 std::vector(空间优化)或 std::vector(访问更快);std::bitset 适合编译期确定大小的场景

多哈希函数实现(推荐方案)

避免引入第三方库,可用一个高质量哈希(如 std::hash<:string>)配合不同种子生成多个哈希值:

size_t hash_i(const std::string& s, size_t seed) {
    std::hash h;
    // 将 seed 混入字符串(简单有效)
    return h(s + std::to_string(seed));
}

更健壮的做法是使用 std::hash 对同一字符串多次哈希(通过 reinterpret_cast 搅拌字节),但更常用的是基于一个基础哈希(如 Murmur3)做 k 次扰动。以下是轻量级实现:

  • std::hash<:string> 得到一个 64 位 hash 值
  • 拆成高 32 位和低 32 位,用线性组合生成 k 个独立哈希:(hash1 + i * hash2 + i*i * hash3) % m
  • 这样只需 2~3 次基础哈希,就能模拟 k 个独立分布

完整可运行示例(简洁版)

以下是一个支持字符串插入/查询、自动计算参数的 BloomFilter 类(无外部依赖):

#include 
#include 
#include 
#include 
#include 

class BloomFilter { private: std::vector bits; size_t m, k;

// 快速哈希:用 std::hash 生成两个基础值,再线性组合
size_t hash(const std::string& s, size_t i) const {
    std::hash h;
    size_t h1 = h(s);
    size_t h2 = h(s + "salt"); // 简单扰动
    return (h1 + i * h2 + i * i) % m;
}

public: BloomFilter(size_t n, double error_rate = 0.01) { // 计算最优 m 和 k(向上取整) m = static_cast(-n std::log(error_rate) / (std::log(2) std::log(2))); k = static_cast(m / n * std::log(2)); if (k == 0) k = 1; bits.resize(m, false); }

void insert(const std::string& s) {
    for (size_t i = 0; i < k; ++i) {
        size_t idx = hash(s, i);
        bits[idx] = true;
    }
}

bool may_contain(const std::string& s) const {
    for (size_t i = 0; i < k; ++i) {
        size_t idx = hash(s, i);
        if (!bits[idx]) return false;
    }
    return true; // 所有位置都为 true → 可能存在(可能误判)
}

};

// 使用示例 int main() { BloomFilter bf(1000, 0.01);

bf.insert("apple");
bf.insert("banana");

std::cout << bf.may_contain("apple") << "\n";   // 1
std::cout << bf.may_contain("cherry") << "\n"; // 0 或 1(小概率为 1)

}

注意:该示例用字符串拼接做扰动,仅用于教学;生产环境建议用 MurmurHash3 或 CityHash,并预计算哈希种子提升性能。

进阶优化建议

若需更高性能或工业级使用:

  • std::vector 替代 std::vector,按位操作(|=, &= ~)批量设置,提升吞吐
  • 将 k 个哈希封装为 constexpr 函数(C++20),支持编译期确定
  • 添加 reset()size()estimated_error_rate() 等辅助接口
  • 考虑并发安全:加读写锁,或用 std::atomic(但 vector 不支持原子访问,需换底层存储)


# app  # 字节  # ai  # c++  # ios  # apple  # stream  # String  # if  # 封装  # Filter  # 字符串  # bool  # int  # double  # 接口  # public  # 并发  # 算法  # 多个  # 多哈  # 最优  # 的是  # 是一个  # 进阶  # 就能  # 只需  # 能在  # 更高 


相关文章: 如何做网站制作流程,*游戏网站怎么搭建?  ,有什么在线背英语单词效率比较高的网站?  制作网站外包平台,自动化接单网站有哪些?  宝塔面板创建网站无法访问?如何快速排查修复?  如何在服务器上三步完成建站并提升流量?  建站之星后台管理:高效配置与模板优化提升用户体验  建站之星如何实现PC+手机+微信网站五合一建站?  如何在Windows服务器上快速搭建网站?  如何选择靠谱的建站公司加盟品牌?  如何用wdcp快速搭建高效网站?  南京网站制作费用,南京远驱官方网站?  厦门模型网站设计制作公司,厦门航空飞机模型掉色怎么办?  寿县云建站:智能SEO优化与多行业模板快速上线指南  如何用PHP工具快速搭建高效网站?  建站之星3.0如何解决常见操作问题?  c# await 一个已经完成的Task会发生什么  简单实现Android文件上传  网站制作的步骤包括,正确网址格式怎么写?  建站之星在线客服如何快速接入解答?  个人网站制作流程图片大全,个人网站如何注销?  linux top下的 minerd 木马清除方法  如何自定义建站之星网站的导航菜单样式?  如何在Golang中引入测试模块_Golang测试包导入与使用实践  制作证书网站有哪些,全国城建培训中心证书查询官网?  c# 在ASP.NET Core中管理和取消后台任务  教学网站制作软件,学习*后期制作的网站有哪些?  内部网站制作流程,如何建立公司内部网站?  网站制作员失业,怎样查看自己网站的注册者?  c++怎么用jemalloc c++替换默认内存分配器【性能】  高性能网站服务器部署指南:稳定运行与安全配置优化方案  山东云建站价格为何差异显著?  php json中文编码为null的解决办法  如何快速搭建高效香港服务器网站?  如何快速搭建高效可靠的建站解决方案?  建站之星如何保障用户数据免受黑客入侵?  车管所网站制作流程,交警当场开简易程序处罚决定书,在交警网站查询不到怎么办?  唐山网站制作公司有哪些,唐山找工作哪个网站最靠谱?  如何通过多用户协作模板快速搭建高效企业网站?  儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?  小建面朝正北,A点实际方位是否存在偏差?  建站之星伪静态规则如何正确配置?  建站主机类型有哪些?如何正确选型  宝华建站服务条款解析:五站合一功能与SEO优化设置指南  如何在建站之星绑定自定义域名?  Dapper的Execute方法的返回值是什么意思 Dapper Execute返回值详解  如何快速搭建个人网站并优化SEO?  如何快速上传建站程序避免常见错误?  Java解压缩zip - 解压缩多个文件或文件夹实例  C#如何序列化对象为XML XmlSerializer用法  招商网站制作流程,网站招商广告语? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。