面试官:如何在十亿个单词字典中,判断某个单词是否存在?(布隆过滤器)

2023-11-07 10:18

本文主要是介绍面试官:如何在十亿个单词字典中,判断某个单词是否存在?(布隆过滤器),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

如何在十亿个单词表中查找某个单词是否出现呢?答案已经给出来了,那就是使用布隆过滤器。那这个布隆过滤器是什么呢?下面就好好讲讲,方便在面试中提高你的zhuangbility。

一、认识布隆过滤器

1、概念

布隆过滤器其实就是加快判定一个元素是否在集合中出现的方法。比如说在一个大字典中,要查找某个单词是否存在,于是我们就可以使用布隆过滤器,快速高效省时省力。

2、原理

既然布隆过滤器这么优秀,他是如何实现的呢?举一个比较黄一点的例子,未成年人勿进,我们知道在我们身边充斥着各种各样的XX网站,为了不毒害我们祖国的花朵,于是国家网警就开始对这些网站进行割除过滤,然后关闭。关闭的时候呢就是关闭他的地址。现在问题来了。

这些网站的地址其实是不停的更换的,这些垃圾网站和正常网站加起来全世界据统计也有几十亿个。这些网警拿到一个地址之后总不能到数据库里面一个一个去比较吧,这就带来了一系列问题。

(1)网站数量太多,存储起来比较麻烦。一个地址最起码有32个字节,一亿个地址就需要1.6G的内存。

(2)一个一个比较,太费时间了。

布隆过滤器是如何高效的呢?他的底层其实是一个特比长的二进制向量和一系列随机映射函数。我们存储一亿个垃圾网站地址。

(1)第一步:建立一个32亿二进制(比特),也就是4亿字节的向量。全部置0。

在这里插入图片描述

(2)第二步:网警用八个不同的随机数产生器(F1,F2, …,F8) 产生八个信息指纹(f1, f2, …, f8)。

(3)第三步:用一个随机数产生器 G 把这八个信息指纹映射到 1 到32亿中的八个自然数 g1, g2, …,g8。

(4)第四步:把这八个位置的二进制全部设置为一。

在这里插入图片描述

OK,这就是其原理,现在网警把所有的垃圾网站地址全部存储下来了,有一天网警查到了一个可疑的网站,想判断一下是否是XX网站,于是就开始检查了。查询可疑网站是否存在集合中的时候,通过同样的方法将可疑网站通过哈希映射到32亿个比特位数组上的8个点。如果8个点的其中有一个点不为1,则可以判断该元素一定不存在集合中。

注意:如果8个点全部是1,也不能判断钙元素一定存在集合中,有一定的误差率。

二、代码实现布隆过滤器

上面只是给出了其原理,下面我们代码实现一下。

public   class  MyBloomFilter {// 2 << 25表示32亿个比特位private static final int DEFAULT_SIZE =  2 << 25 ;private static final int[] seeds = new int [] {3,5,7,11,13,19,23,37 };//这么大存储在BitSetprivate  BitSet  bits = new BitSet(DEFAULT_SIZE);private  SimpleHash[] func  = new  SimpleHash[seeds.length];public   static   void  main(String[] args) {//可疑网站String value = "www.java的架构师技术栈.com" ;MyBloomFilter filter = new MyBloomFilter();//加入之前判断一下System.out.println(filter.contains(value));filter.add(value);//加入之后判断一下System.out.println(filter.contains(value));}//构造函数public  MyBloomFilter() {for  ( int  i  =   0 ; i  <  seeds.length; i ++ ) {func[i]  =   new  SimpleHash(DEFAULT_SIZE, seeds[i]);}}//添加网站public   void  add(String value) {for  (SimpleHash f : func) {bits.set(f.hash(value),  true );}}//判断可疑网站是否存在public   boolean  contains(String value) {if  (value  ==   null ) {return   false ;}boolean  ret  =   true ;for  (SimpleHash f : func) {//核心就是通过“与”的操作ret  =  ret  &&  bits.get(f.hash(value));}return  ret;}
}

还有一个SimpleHash,我们看一下

  public   static   class  SimpleHash {private  int  cap;private  int  seed;public  SimpleHash( int  cap,  int  seed) {this .cap  =  cap;this .seed  =  seed;}public   int  hash(String value) {int  result  =   0 ;int  len  =  value.length();for  ( int  i  =   0 ; i  <  len; i ++ ) {result  =  seed  *  result  +  value.charAt(i);}return  (cap  -   1 )  &  result;}}
  • value.charAt(i);
    }
    return (cap - 1 ) & result;
    }
    }
    ``

这就是布隆过滤器的实现。
在这里插入图片描述

这篇关于面试官:如何在十亿个单词字典中,判断某个单词是否存在?(布隆过滤器)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/362949

相关文章

poj 3259 uva 558 Wormholes(bellman最短路负权回路判断)

poj 3259: 题意:John的农场里n块地,m条路连接两块地,w个虫洞,虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts。 任务是求你会不会在从某块地出发后又回来,看到了离开之前的自己。 判断树中是否存在负权回路就ok了。 bellman代码: #include<stdio.h>const int MaxN = 501;//农场数const int

zoj 1721 判断2条线段(完全)相交

给出起点,终点,与一些障碍线段。 求起点到终点的最短路。 枚举2点的距离,然后最短路。 2点可达条件:没有线段与这2点所构成的线段(完全)相交。 const double eps = 1e-8 ;double add(double x , double y){if(fabs(x+y) < eps*(fabs(x) + fabs(y))) return 0 ;return x + y ;

POJ1269 判断2条直线的位置关系

题目大意:给两个点能够确定一条直线,题目给出两条直线(由4个点确定),要求判断出这两条直线的关系:平行,同线,相交。如果相交还要求出交点坐标。 解题思路: 先判断两条直线p1p2, q1q2是否共线, 如果不是,再判断 直线 是否平行, 如果还不是, 则两直线相交。  判断共线:  p1p2q1 共线 且 p1p2q2 共线 ,共线用叉乘为 0  来判断,  判断 平行:  p1p

Codeforces Round #113 (Div. 2) B 判断多边形是否在凸包内

题目点击打开链接 凸多边形A, 多边形B, 判断B是否严格在A内。  注意AB有重点 。  将A,B上的点合在一起求凸包,如果凸包上的点是B的某个点,则B肯定不在A内。 或者说B上的某点在凸包的边上则也说明B不严格在A里面。 这个处理有个巧妙的方法,只需在求凸包的时候, <=  改成< 也就是说凸包一条边上的所有点都重复点都记录在凸包里面了。 另外不能去重点。 int

POJ2001字典树

给出n个单词,求出每个单词的非公共前缀,如果没有,则输出自己。 import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.io.UnsupportedEncodingException;

easyui同时验证账户格式和ajax是否存在

accountName: {validator: function (value, param) {if (!/^[a-zA-Z][a-zA-Z0-9_]{3,15}$/i.test(value)) {$.fn.validatebox.defaults.rules.accountName.message = '账户名称不合法(字母开头,允许4-16字节,允许字母数字下划线)';return fal

【408DS算法题】039进阶-判断图中路径是否存在

Index 题目分析实现总结 题目 对于给定的图G,设计函数实现判断G中是否含有从start结点到stop结点的路径。 分析实现 对于图的路径的存在性判断,有两种做法:(本文的实现均基于邻接矩阵存储方式的图) 1.图的BFS BFS的思路相对比较直观——从起始结点出发进行层次遍历,遍历过程中遇到结点i就表示存在路径start->i,故只需判断每个结点i是否就是stop

linux 判断某个命令是否安装

linux 判断某个命令是否安装 if ! [ -x "$(command -v git)" ]; thenecho 'Error: git is not installed.' >&2exit 1fi

Redis中使用布隆过滤器解决缓存穿透问题

一、缓存穿透(失效)问题 缓存穿透是指查询一个一定不存在的数据,由于缓存中没有命中,会去数据库中查询,而数据库中也没有该数据,并且每次查询都不会命中缓存,从而每次请求都直接打到了数据库上,这会给数据库带来巨大压力。 二、布隆过滤器原理 布隆过滤器(Bloom Filter)是一种空间效率很高的随机数据结构,它利用多个不同的哈希函数将一个元素映射到一个位数组中的多个位置,并将这些位置的值置

每日一练7:简写单词(含链接)

1.链接 简写单词_牛客题霸_牛客网 2.题目 3.代码1(错误经验) #include <iostream>#include <string>using namespace std;int main() {string s;string ret;int count = 0;while(cin >> s)for(auto a : s){if(count == 0){if( a <=