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

Posted 愚公要移山

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面试官:如何在十亿个单词字典中,判断某个单词是否存在?(布隆过滤器)相关的知识,希望对你有一定的参考价值。

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

一、认识布隆过滤器

1、概念

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

2、原理

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

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

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

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

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

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

注意:如果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 };
     //这么大存储在BitSet
     private  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  SimpleHashint  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;
        }
    }

这就是布隆过滤器的实现。

以上是关于面试官:如何在十亿个单词字典中,判断某个单词是否存在?(布隆过滤器)的主要内容,如果未能解决你的问题,请参考以下文章

每日写题分享--单词拆分/动态规划/剪枝

Trie树(字典树)

面试被虐如何只用2GB内存从20亿,40亿,80亿个整数中找到出现次数最多的数?

面试被虐如何只用2GB内存从20亿,40亿,80亿个整数中找到出现次数最多的数?

判断字符串中是否包含某个单词

通过删除字母匹配到字典里最长单词--双指针or自动机预处理?