【C++】-- 哈希应用之布隆过滤器(二)

简介: 【C++】-- 哈希应用之布隆过滤器

五、布隆过滤器应用

1.找文件交集

给两个文件,分别有100亿个query,只有1G内存,如何找到两个文件交集?请给出近似算法和精确算法。

(1)近似算法

判断交集本质上是判断在不在,读取第一个query,将元素都映射到布隆过滤器中,再读取第二个文件中的query,判断每个query在不在布隆过滤器中,如果在就是交集。

(2)精确算法

假设每个query是20字节,100亿个query就是100亿*20个字节=2000亿KB=200GB,使用哈希切分

2.扩展布隆过滤器

如何扩展BloomFilter使得它支持删除元素的操作?

       布隆过滤器本不支持删除,这是由于布隆过滤器判断一个元素在不在时可能会存在误判,删除它对应的bit位时会影响其他元素,且多个元素可能会映射到同一bit位,因此删除某一bit位时会影响其他元素,可能会导致其他元素也被删除。

       不过可以采用以下方法让布隆过滤器支持删除元素:

       在布隆过滤器中找到该元素后,由于使用多个位表示一个元素,因此可以对布隆过滤器的每一个bit位使用计数来代替0/1(在不在),当有多个元素映射到该bit位时,该bit计数++ ,删除时,该bit计数--。

六、哈希应用

给一个超过100G大小的log file, log中存着IP地址, 设计算法找到出现次数最多的IP地址? 与上题条件相同,如何找到top K的IP?如何直接用Linux系统命令实现?

1.找到出现次数最多的IP

(1)文件超过100G,不能加载到内存中,就需要将文件进行哈希切分,通过一个哈希函数,将log文件中的每个IP都转换为整数,如果IP相同,那么转换后的整数也相同,就会映射到同一个小文件中。

(2)切分成小文件后就可以加载到内存了,对于每次加载到内存的小文件,使用map<string,int>对该小文件中的所有IP进行次数统计,找出出现次数最多的IP。

(3)将每个文件中出现次数最多的IP再使用map<string,int>进行统计,就能找到出现次数最多的那个IP了。

另外:将文件切分为100个小文件,这100个小文件并不是均匀切分的,有的可能会小于1G,有的则可能会大于1G,当有几十个文件都大于1G时,可以考虑将文件直接切分为200份,而不是100份,这样每个小文件大约为512MB。

2. 找到top K的IP

(1)对100G的文件建堆,内存放不下,因此还是要切分成小文件,如上图中将100G的大文件利用哈希函数切分成100个小文件。

(2)将第一个文件加载到内存中,对第一个小文件建有K个元素的小堆,只要比堆顶元素大就进堆,最后堆里剩下的就是第一个小文件中出现次数最多的K个IP。

(3)将剩下的其它小文件依次加载到内存,每加载一个小文件,就将该小文件中的所有IP和堆顶元素进行比较,只要比堆顶元素大,就进堆。最后堆里留下的就是出现次数最多的K个IP。

3.用Linux系统命令实现找到top K的IP

假如有以下文件IP.log:

1. 192.168.1.5
2. 69.52.220.44
3. 10.152.16.23
4. 192.168.3.10
5. 192.168.1.4
6. 192.168.2.1
7. 192.168.0.9
8. 10.152.16.23
9. 192.163.0.9
10. 192.168.0.9
11. 69.52.220.44
12. 192.168.1.4
13. 192.168.1.5
14. 192.163.0.9
15. 192.168.2.1
16. 192.168.0.1
17. 192.168.0.2
18. 192.168.0.9
19. 9.9.9.9
20. 127.0.0.1
21. 192.168.0.90
22. 192.168.0.89
23. 192.168.0.8
24. 192.168.0.9
25. 192.163.0.9

(1)按行排序,并将结果输出到标准输出

sort 文件名

(2)统计并显示文本文件中出现的行或列的次数

uniq -c

(3)根据出现次数倒序排序

sort -r

(4)查看开头K行

head -k

显示出现次数最多的前K个IP

相关文章
|
21天前
|
存储 并行计算 安全
C++多线程应用
【10月更文挑战第29天】C++ 中的多线程应用广泛,常见场景包括并行计算、网络编程中的并发服务器和图形用户界面(GUI)应用。通过多线程可以显著提升计算速度和响应能力。示例代码展示了如何使用 `pthread` 库创建和管理线程。注意事项包括数据同步与互斥、线程间通信和线程安全的类设计,以确保程序的正确性和稳定性。
|
1月前
|
存储 编译器 C++
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
53 2
|
2月前
|
编译器 C++
【C++核心】函数的应用和提高详解
这篇文章详细讲解了C++函数的定义、调用、值传递、常见样式、声明、分文件编写以及函数提高的内容,包括函数默认参数、占位参数、重载等高级用法。
22 3
|
1月前
|
存储 算法 C++
【算法】哈希映射(C/C++)
【算法】哈希映射(C/C++)
|
3月前
|
存储 算法 C++
C++ STL应用宝典:高效处理数据的艺术与实战技巧大揭秘!
【8月更文挑战第22天】C++ STL(标准模板库)是一组高效的数据结构与算法集合,极大提升编程效率与代码可读性。它包括容器、迭代器、算法等组件。例如,统计文本中单词频率可用`std::map`和`std::ifstream`实现;对数据排序及找极值则可通过`std::vector`结合`std::sort`、`std::min/max_element`完成;而快速查找字符串则适合使用`std::set`配合其内置的`find`方法。这些示例展示了STL的强大功能,有助于编写简洁高效的代码。
48 2
|
3月前
|
存储 编译器 C++
C++多态实现的原理:深入探索与实战应用
【8月更文挑战第21天】在C++的浩瀚宇宙中,多态性(Polymorphism)无疑是一颗璀璨的星辰,它赋予了程序高度的灵活性和可扩展性。多态允许我们通过基类指针或引用来调用派生类的成员函数,而具体调用哪个函数则取决于指针或引用所指向的对象的实际类型。本文将深入探讨C++多态实现的原理,并结合工作学习中的实际案例,分享其技术干货。
74 0
|
6天前
|
存储 编译器 C++
【c++】类和对象(中)(构造函数、析构函数、拷贝构造、赋值重载)
本文深入探讨了C++类的默认成员函数,包括构造函数、析构函数、拷贝构造函数和赋值重载。构造函数用于对象的初始化,析构函数用于对象销毁时的资源清理,拷贝构造函数用于对象的拷贝,赋值重载用于已存在对象的赋值。文章详细介绍了每个函数的特点、使用方法及注意事项,并提供了代码示例。这些默认成员函数确保了资源的正确管理和对象状态的维护。
29 4
|
7天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
25 4
|
30天前
|
存储 编译器 对象存储
【C++打怪之路Lv5】-- 类和对象(下)
【C++打怪之路Lv5】-- 类和对象(下)
27 4
|
30天前
|
编译器 C语言 C++
【C++打怪之路Lv4】-- 类和对象(中)
【C++打怪之路Lv4】-- 类和对象(中)
23 4