0

0

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

尼克

尼克

发布时间:2026-01-01 09:39:34

|

791人浏览过

|

来源于php中文网

原创

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

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

用 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

立即学习C++免费学习笔记(深入)”;

实际中可简化为:

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

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

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

讯飞智作-讯飞配音
讯飞智作-讯飞配音

讯飞智作是一款集AI配音、虚拟人视频生成、PPT生成视频、虚拟人定制等多功能的AI音视频生产平台。已广泛应用于媒体、教育、短视频等领域。

下载
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 不支持原子访问,需换底层存储)

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

312

2023.08.02

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

713

2023.08.22

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

248

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

205

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1435

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

609

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

547

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

539

2024.04.29

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Java 教程
Java 教程

共578课时 | 40.1万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号