- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章C++哈希应用的位图和布隆过滤器由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
所谓位图,就是用每一位来存放某种状态,适用于海量数据,数据无重复的场景。通常是用来判断某个数据存不存在的.
给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。【腾讯】 。
数据是否在给定的整形数据中,结果是在或者不在,刚好是两种状态,那么可以使用一个二进制比特位来代表数据是否存在的信息,如果二进制比特位为1,代表存在,为0代表不存在。比如:
#include<iostream>#include<vector>#include<math.h>namespace yyw{class bitset{public:bitset(size_t N){ _bits.resize(N / 32 + 1, 0); _num = 0;}//将x位的比特位设置为1void set(size_t x){ size_t index = x / 32; //映射出x在第几个整形 size_t pos = x % 32; //映射出x在整形的第几个位置 _bits[index] |= (1 << pos); _num++;}//将x位的比特位设置为0void reset(size_t x){ size_t index = x / 32; size_t pos = x % 32; _bits[index] &= ~(1 << pos); _num--;}//判断x位是否在不在bool test(size_t x){ size_t index = x / 32; size_t pos = x % 32; return _bits[index] & (1 << pos);}//位图中比特位的总个数size_t size(){ return _num;}private:std::vector<int> _bits;size_t _num; //映射存储了多少个数据};void tes_bitset(){bitset bs(100);bs.set(99);bs.set(98);bs.set(97);bs.set(10);for (size_t i = 0; i < 100; i++){ printf("[%d]:%d\n", i, bs.test(i));}//40亿个数据,判断某个数是否在数据中//bs.reset(-1);//bs.reset(pow(2, 32));}}
我们在使用新闻客户端看新闻时,它会给我们不停地推荐新的内容,它每次推荐时要去重,去掉那些已经看过的内容。问题来了,新闻客户端推荐系统如何实现推送去重的? 用服务器记录了用户看过的所有历史记录,当推荐系统推荐新闻时会从每个用户的历史记录里进行筛选,过滤掉那些已经存在的记录。 如何快速查找呢?
布隆过滤器是由布隆(Burton Howard Bloom)在1970年提出的 一种紧凑型的、比较巧妙的概率型数据结构,特点是高效地插入和查询,可以用来告诉你 “某样东西一定不存在或者可能存在”,它是用多个哈希函数,将一个数据映射到位图结构中。此种方式不仅可以提升查询效率,也可以节省大量的内存空间.
布隆过滤器底层是位图:
struct HashStr1{//BKDR1size_t operator()(const std::string& str){ size_t hash = 0; for (size_t i = 0; i < str.size(); i++) { hash *= 131; hash += str[i]; } return hash;}};struct HashStr2{//RSHashsize_t operator()(const std::string& str){ size_t hash = 0; size_t magic = 63689; //魔数 for (size_t i = 0; i < str.size();i++) { hash *= magic; hash += str[i]; magic *= 378551; } return hash;}};struct HashStr3{//SDBHashsize_t operator()(const std::string& str){ size_t hash = 0; for (size_t i = 0; i < str.size(); i++) { hash *= 65599; hash += str[i]; } return hash;}};//假设布隆过滤器元素类型为K,如果类型为K要自己配置仿函数template<class K,class Hash1=HashStr1,class Hash2=HashStr2,class Hash3=HashStr3>class bloomfilter{public:bloomfilter(size_t num) :_bs(5*num) , _N(5*num){}void set(const K& key){ size_t index1 = Hash1()(key) % _N; size_t index2 = Hash2()(key) % _N; size_t index3 = Hash3()(key) % _N; _bs.set(index1); //三个位置都设置为1 _bs.set(index2); _bs.set(index3);}}
布隆过滤器的思想是将一个元素用多个哈希函数映射到一个位图中,因此被映射到的位置的比特位一定为1。所以可以按照以下方式进行查找:分别计算每个哈希值对应的比特位置存储的是否为零,只要有一个为零,代表该元素一定不在哈希表中,否则可能在哈希表中.
bool test(const K& key){ size_t index1 = Hash1()(key) % _N; if (_bs.test(index1) == false) { return false; } size_t index2 = Hash1()(key) % _N; if (_bs.test(index2) == false) { return false; } size_t index3 = Hash3()(key) % _N; if (_bs.test(index3) == false) { return false; } return true; //但是这里也不一定是真的在,还有可能存在误判 //判断不在是正确的,判断在可能存在误判}
注意:布隆过滤器如果说某个元素不存在时,该元素一定不存在,如果该元素存在时,该元素可能存在,因为有些哈希函数存在一定的误判.
比如:在布隆过滤器中查找"alibaba"时,假设3个哈希函数计算的哈希值为:1、3、7,刚好和其他元素的比特位重叠,此时布隆过滤器告诉该元素存在,但实该元素是不存在的.
布隆过滤器不能直接支持删除工作,因为在删除一个元素时,可能会影响其他元素.
比如:删除上图中"tencent"元素,如果直接将该元素所对应的二进制比特位置0,“baidu”元素也被删除了,因为这两个元素在多个哈希函数计算出的比特位上刚好有重叠.
一种支持删除的方法:将布隆过滤器中的每个比特位扩展成一个小的计数器,插入元素时给k个计数器(k个哈希函数计算出的哈希地址)加一,删除元素时,给k个计数器减一,通过多占用几倍存储空间的代价来增加删除操作.
缺陷:
位图 。
①给一个超过100G大小的log file, log中存着IP地址, 设计算法找到出现次数最多的IP地址? 与上题条件相同,如何找到top K的IP?如何直接用Linux系统命令实现?
①给定100亿个整数,设计算法找到只出现一次的整数?
②给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集?
③位图应用变形:1个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的所有整数?
①给两个文件,分别有100亿个query,我们只有1G内存,如何找到两个文件交集?分别给出精确算法和近似算法?
②如何扩展BloomFilter使得它支持删除元素的操作?
到此这篇关于C++哈希应用的位图和布隆过滤器的文章就介绍到这了,更多相关C++哈希应用位图与布隆过滤器内容请搜索我以前的文章或继续浏览下面的相关文章希望大家以后多多支持我! 。
原文链接:https://blog.csdn.net/qq_44918090/article/details/120000787 。
最后此篇关于C++哈希应用的位图和布隆过滤器的文章就讲到这里了,如果你想了解更多关于C++哈希应用的位图和布隆过滤器的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在通过 labrepl 工作,我看到了一些遵循此模式的代码: ;; Pattern (apply #(apply f %&) coll) ;; Concrete example user=> (a
我从未向应用商店提交过应用,但我会在不久的将来提交。 到目前为止,我对为 iPhone 而非 iPad 进行设计感到很自在。 我了解,通过将通用PAID 应用放到应用商店,客户只需支付一次就可以同时使
我有一个应用程序,它使用不同的 Facebook 应用程序(2 个不同的 AppID)在 Facebook 上发布并显示它是“通过 iPhone”/“通过 iPad”。 当 Facebook 应用程序
我有一个要求,我们必须通过将网站源文件保存在本地 iOS 应用程序中来在 iOS 应用程序 Webview 中运行网站。 Angular 需要服务器来运行应用程序,但由于我们将文件保存在本地,我们无法
所以我有一个单页客户端应用程序。 正常流程: 应用程序 -> OAuth2 服务器 -> 应用程序 我们有自己的 OAuth2 服务器,因此人们可以登录应用程序并获取与用户实体关联的 access_t
假设我有一个安装在用户设备上的 Android 应用程序 A,我的应用程序有一个 AppWidget,我们可以让其他 Android 开发人员在其中以每次安装成本为基础发布他们的应用程序推广广告。因此
Secrets of the JavaScript Ninja中有一个例子它提供了以下代码来绕过 JavaScript 的 Math.min() 函数,该函数需要一个可变长度列表。 Example:
当我分别将数组和对象传递给 function.apply() 时,我得到 NaN 的 o/p,但是当我传递对象和数组时,我得到一个数字。为什么会发生这种情况? 由于数组也被视为对象,为什么我无法使用它
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界. 这篇CFSDN的博客文章ASP转换格林威治时间函数DateDiff()应用由作者收集整理,如果你
我正在将列表传递给 map并且想要返回一个带有合并名称的 data.frame 对象。 例如: library(tidyverse) library(broom) mtcars %>% spl
我有一个非常基本的问题,但我不知道如何实现它:我有一个返回数据框,其中每个工具的返回值是按行排列的: tmp<-as.data.frame(t(data.frame(a=rnorm(250,0,1)
我正在使用我的 FB 应用创建群组并邀请用户加入我的应用群组,第一次一切正常。当我尝试创建另一个组时,出现以下错误: {"(OAuthException - #4009) (#4009) 在有更多用户
我们正在开发一款类似于“会说话的本”应用程序的 child 应用程序。它包含大量用于交互式动画的 JPEG 图像序列。 问题是动画在 iPad Air 上播放正常,但在 iPad 2 上播放缓慢或滞后
我关注 clojure 一段时间了,它的一些功能非常令人兴奋(持久数据结构、函数式方法、不可变状态)。然而,由于我仍在学习,我想了解如何在实际场景中应用,证明其好处,然后演化并应用于更复杂的问题。即,
我开发了一个仅使用挪威语的应用程序。该应用程序不使用本地化,因为它应该仅以一种语言(挪威语)显示。但是,我已在 Info.plist 文件中将“本地化 native 开发区域”设置为“no”。我还使用
读完 Anthony's response 后上a style-related parser question ,我试图说服自己编写单体解析器仍然可以相当紧凑。 所以而不是 reference ::
multicore 库中是否有类似 sapply 的东西?还是我必须 unlist(mclapply(..)) 才能实现这一点? 如果它不存在:推理是什么? 提前致谢,如果这是一个愚蠢的问题,我们深表
我喜欢在窗口中弹出结果,以便更容易查看和查找(例如,它们不会随着控制台继续滚动而丢失)。一种方法是使用 sink() 和 file.show()。例如: y <- rnorm(100); x <- r
我有一个如下所示的 spring mvc Controller @RequestMapping(value="/new", method=RequestMethod.POST) public Stri
我正在阅读 StructureMap关于依赖注入(inject),首先有两部分初始化映射,具体类类型的接口(interface),另一部分只是实例化(请求实例)。 第一部分需要配置和设置,这是在 Bo
我是一名优秀的程序员,十分优秀!