日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

布隆过滤器(Bloom Filter)的原理和实现

發(fā)布時(shí)間:2023/12/10 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 布隆过滤器(Bloom Filter)的原理和实现 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

布隆過濾器使用場(chǎng)景

之前在《數(shù)學(xué)之美》里面看到過布隆過濾器的介紹。那么什么場(chǎng)景下面需要使用布隆過濾器呢?

看下下面幾個(gè)問題

  • 字處理軟件中,需要檢查一個(gè)英語(yǔ)單詞是否拼寫正確
  • 在 FBI,一個(gè)嫌疑人的名字是否已經(jīng)在嫌疑名單上
  • 在網(wǎng)絡(luò)爬蟲里,一個(gè)網(wǎng)址是否被訪問過
  • yahoo, gmail等郵箱垃圾郵件過濾功能

以上這些場(chǎng)景有個(gè)共同的問題:如何查看一個(gè)東西是否在有大量數(shù)據(jù)的池子里面。

通常的做法有如下幾種思路:

  • 數(shù)組
  • 鏈表
  • 樹、平衡二叉樹、Trie
  • Map (紅黑樹)
  • 哈希表

哈希函數(shù)

哈希函數(shù)的概念是:將任意大小的數(shù)據(jù)轉(zhuǎn)換成特定大小的數(shù)據(jù)的函數(shù),轉(zhuǎn)換后的數(shù)據(jù)稱為哈希值或哈希編碼。下面是一幅示意圖

?

可以明顯的看到,原始數(shù)據(jù)經(jīng)過哈希函數(shù)的映射后稱為了一個(gè)個(gè)的哈希編碼,數(shù)據(jù)得到壓縮。哈希函數(shù)是實(shí)現(xiàn)哈希表和布隆過濾器的基礎(chǔ)。

布隆過濾器介紹

  • 巴頓.布隆于一九七零年提出
  • 一個(gè)很長(zhǎng)的二進(jìn)制向量 (位數(shù)組)
  • 一系列隨機(jī)函數(shù) (哈希)
  • 空間效率和查詢效率高
  • 不會(huì)漏判,但是有一定的誤判率(哈希表是精確匹配)

布隆過濾器原理

布隆過濾器(Bloom Filter)的核心實(shí)現(xiàn)是一個(gè)超大的位數(shù)組和幾個(gè)哈希函數(shù)。假設(shè)位數(shù)組的長(zhǎng)度為m,哈希函數(shù)的個(gè)數(shù)為k

以上圖為例,具體的操作流程:假設(shè)集合里面有3個(gè)元素{x, y, z},哈希函數(shù)的個(gè)數(shù)為3。首先將位數(shù)組進(jìn)行初始化,將里面每個(gè)位都設(shè)置位0。對(duì)于集合里面的每一個(gè)元素,將元素依次通過3個(gè)哈希函數(shù)進(jìn)行映射,每次映射都會(huì)產(chǎn)生一個(gè)哈希值,這個(gè)值對(duì)應(yīng)位數(shù)組上面的一個(gè)點(diǎn),然后將位數(shù)組對(duì)應(yīng)的位置標(biāo)記為1。查詢W元素是否存在集合中的時(shí)候,同樣的方法將W通過哈希映射到位數(shù)組上的3個(gè)點(diǎn)。如果3個(gè)點(diǎn)的其中有一個(gè)點(diǎn)不為1,則可以判斷該元素一定不存在集合中。反之,如果3個(gè)點(diǎn)都為1,則該元素可能存在集合中。注意:此處不能判斷該元素是否一定存在集合中,可能存在一定的誤判率。可以從圖中可以看到:假設(shè)某個(gè)元素通過映射對(duì)應(yīng)下標(biāo)為4,5,6這3個(gè)點(diǎn)。雖然這3個(gè)點(diǎn)都為1,但是很明顯這3個(gè)點(diǎn)是不同元素經(jīng)過哈希得到的位置,因此這種情況說明元素雖然不在集合中,也可能對(duì)應(yīng)的都是1,這是誤判率存在的原因。

添加元素

  • 將要添加的元素給k個(gè)哈希函數(shù)
  • 得到對(duì)應(yīng)于位數(shù)組上的k個(gè)位置
  • 將這k個(gè)位置設(shè)為1

查詢?cè)?/h1>
  • 將要查詢的元素給k個(gè)哈希函數(shù)
  • 得到對(duì)應(yīng)于位數(shù)組上的k個(gè)位置
  • 如果k個(gè)位置有一個(gè)為0,則肯定不在集合中
  • 如果k個(gè)位置全部為1,則可能在集合中簡(jiǎn)易實(shí)現(xiàn)

簡(jiǎn)易實(shí)現(xiàn)

import java.util.BitSet;/*** Created by haicheng.lhc on 18/05/2017.** @author haicheng.lhc* @date 2017/05/18*/ public class SimpleBloomFilter {private static final int DEFAULT_SIZE = 2 << 24;private static final int[] seeds = new int[] {7, 11, 13, 31, 37, 61,};private BitSet bits = new BitSet(DEFAULT_SIZE);private SimpleHash[] func = new SimpleHash[seeds.length];public static void main(String[] args) {String value = " stone2083@yahoo.cn ";SimpleBloomFilter filter = new SimpleBloomFilter();System.out.println(filter.contains(value));filter.add(value);System.out.println(filter.contains(value));}public SimpleBloomFilter() {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;}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;}} }



?

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的布隆过滤器(Bloom Filter)的原理和实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。