0x00 前言
本篇是 大數據算法系列 第一篇《BitMap的原理和實現》,BitMap 的思想的和原理是很多算法的基礎,因此我們以BitMap開篇。
既然是說大數據算法,我們先嘗試給大數據算法一個定義,或者說是限定一下這個系列的範圍。
大數據算法:在給定的資源約束下,以大數據為輸入,在給定時間約束內可以計算出給定問題加過的算法。
大數據算法會有傳統的算法有不一樣的地方:
-
資源有約束
-
時間有約束
-
大數據作為輸入
-
不一定是精確算法
前三點可以看作是對算法的要求,第四點可以看作是在大數據場景下算法可以做出的讓步。比如說在10億的數據中求 count distinct
操作,完全精確的算法會十分占用空間資源,而且也很難在快速計算出結果。如果這時候允許一定的誤差,就可以在極短的時間使用少量的內容算出結果,比如基數估計算法中的Hyperloglog。
本系列會包括 BitMap、Roaring BitMap、Bloom Filter、Counting Bloom Filter、Linear Counting、Loglog Counting、HyperLogLog Counting 等算法。我會把這些算法一個個過一遍,看論文、寫代碼、整理學習筆記。
對於技術人員來講,文章應該做到 圖文碼並茂 ,因此我會盡量做到每篇文章都有原理說明和示例代碼的實現,原理說明會通過配圖的方式來理解,代碼的話會有一個比較簡單的demo。
0x01 原理
基本原理
BitMap 的基本原理就是用一個 bit 來標記某個元素對應的 Value,而 Key 即是該元素。由於采用一 個bit 來存儲一個數據,因此可以大大的節省空間。
我們通過一個具體的例子來說明 BitMap 的原理,假設我們要對 0-31 內的 3 個元素 (10, 17,28) 排序,那麽我們就可以采用 BitMap 方法(假設這些元素沒有重復)。
如下圖,要表示 32 個數,我們就只需要 32 個 bit(4Bytes),首先我們開辟 4Byte 的空間,將這些空間的所有 bit 位都置為 0。
然後,我們要添加(10, 17,28) 這三個數到 BitMap 中,需要的操作就是在相應的位置上將0置為1即可。如下圖,比如現在要插入 10 這個元素,只需要將藍色的那一位變為1即可。
將這些數據插入後,假設我們想對數據進行排序或者檢索數據是否存在,就可以依次遍歷這個數據結構,碰到位為 1 的情況,就當這個數據存在。
字符串映射
BitMap 也可以用來表述字符串類型的數據,但是需要有一層Hash映射,如下圖,通過一層映射關系,可以表述字符串是否存在。
當然這種方式會有 數據碰撞 的問題,但可以通過 Bloom Filter 做一些優化。
0x02 實現
懂原理之後,還是要寫代碼來加深一下理解,這裏用 python 實現一個最基本的版本。
代碼用到了 bitarry 庫來直接操作 bit 數組;用 hashlib 來將字符串映射到數字,以便插入 BitMap。
代碼很簡單,看懂上面的原理的話,很容易就看懂了代碼。
0x03 使用
BitMap 的使用場景很廣泛,比如說 Oracle、Redis 中都有用到 BitMap。當然更多的系統會有比 BitMap 稍微復雜一些的算法,比如 Bloom Filter、Counting Bloom Filter,這些會在後面逐一展開。
下面舉一個在算法中用到 BitMap 來解決問題的例子。
已知某個文件內包含一些電話號碼,每個號碼為8位數字,統計不同號碼的個數。
在這裏就不再做和其它算法的對比,直接說一下 BitMap 的思路。
8 位的整數,相當於是範圍在(0,99999999),也就是說 99999999 個 bit,也就是 12M 左右的內存,比起用類似 HashMap 的方式的話能節省很大的空間。 可以理解為從0 到 99999999 的數字,每個數字對應一個 Bit位,所以只需要 12M 左右的內存表示了所有的 8 位數的電話。
查詢的時候就很簡單了,直接統計有多少位是 1 就可以了。
0x04 總結
BitMap 的思想在面試的時候還是可以用來解決不少問題的,然後在很多系統中也都會用到,算是一種不錯的解決問題的思路。
但是 BitMap 也有一些局限,因此會有其它一些基於 BitMap 的算法出現來解決這些問題。
-
數據碰撞。比如將字符串映射到 BitMap 的時候會有碰撞的問題,那就可以考慮用 Bloom Filter 來解決,Bloom Filter 使用多個 Hash 函數來減少沖突的概率。
-
數據稀疏。又比如要存入(10,8887983,93452134)這三個數據,我們需要建立一個 99999999 長度的 BitMap ,但是實際上只存了3個數據,這時候就有很大的空間浪費,碰到這種問題的話,可以通過引入 Roaring BitMap 來解決。
Tags: 算法 數據 原理 BitMap 可以 給定
文章來源: