判斷一個元素是否在一個集合中
數組 array
查看對應的元素是否在集合中,時間複雜度O(n),遍歷尋找。
假設查找Mango
是否在這裏面,需要遍歷每個元素進行比較,看是否在這裏面,時間複雜度O(n)。
哈希表 hashTable
查看對應的元素是否在集合中,時間複雜度O(1),先通過hash方法,再去查看是否有。
這樣看起來是非常完美的,但是隨着元素數量的增多,hashTable佔用的空間也會非常大。
假設去判斷一百億個URL中是否存在https://www.csdn.net/
這個URL。如果使用hashTable來存儲這麼多數據,也是不現實的。
僅僅是判斷一個元素是否在集合裏,能否將這些數據不用那麼精確存儲,可以聯調想到的是BitMap。
BitMap
簡單來講就是 一段內存,上面只存儲了01兩個數值(聽起來是廢話,計算機內部存儲都是這麼做的),默認的都是0,按照內存開始和內存結束,邏輯上有第幾位第幾位。
可以將某個值通過hash 函數計算之後得到整數,然後將對應位數翻轉爲1。
假設有m個位,n個元素,來推導下情況
-
任意一個位被置爲1的概率爲:
-
任意一個位沒有被置位1的概率爲:
-
插入了n個元素依然沒有被置爲1的概率爲:
- 反過來說,插入n個元素,一個位被置爲1的概率爲:
布隆過濾器
如果使用多個hash函數,將多個位置變爲1,就是布隆過濾器。
初始化
添加geeks
字符串,利用三個hash函數,將1、4、7置爲1
添加nerd
字符串,利用三個hash函數,將3、4、5置爲1,由於上個操作已經把4置爲1了。
添加cat
字符串,利用hash函數,會看到1、3、7都是1。這就是誤報的情況,過濾不是百分百的,而是有概率的。
總結
上面這種保證了,如果有一個位爲0,就是精準的過濾。
所以能保證:不存在的肯定不存在;存在的不一定存在。
Filter 就是布隆過濾器
Storage 就是存儲
主要就是通過給定數據,判斷數據是否在storage中,先通過Filter來過濾下,然後把請求丟到storage中,大大降低了對storage的訪問。