MapReduce是一種編程模型,用於大規模數據集(大於1TB)的並行運算。概念"Map(映射)"和"Reduce(歸約)"
Bit-map空間壓縮和快速排序去重
1. Bit-map的基本思想
32位機器上,對於一個整型數,比如int a=1 在內存中占32bit位,這是為了方便計算機的運算。但是對於某些應用場景而言,這屬於一種巨大的浪費,因為我們可以用對應的32bit位對應存儲十進制的0-31個數,而這就是Bit-map的基本思想。Bit-map算法利用這種思想處理大量數據的排序、查詢以及去重。
Bitmap在用戶群做交集和並集運算的時候也有極大的便利。
2. Bit-map應用之快速排序
假設我們要對0-7內的5個元素(4,7,2,5,3)排序(這里假設這些元素沒有重復),我們就可以采用Bit-map的方法來達到排序的目的。要表示8個數,我們就只需要8個Bit(1Bytes),首先我們開辟1Byte的空間,將這些空間的所有Bit位都置為0,
對應位設置為1:
遍歷一遍Bit區域,將該位是一的位的編號輸出(2,3,4,5,7),這樣就達到了排序的目的,時間復雜度O(n)。
優點:
運算效率高,不需要進行比較和移位;
占用內存少,比如N=10000000;只需占用內存為N/8=1250000Byte=1.25M。
缺點:
所有的數據不能重復。即不可對重復的數據進行排序和查找。
3. Bit-map應用之快速去重
2.5億個整數中找出不重復的整數的個數,內存空間不足以容納這2.5億個整數。
首先,根據“內存空間不足以容納這2.5億個整數”我們可以快速的聯想到Bit-map。下邊關鍵的問題就是怎么設計我們的Bit-map來表示這2.5億個數字的狀態了。其實這個問題很簡單,一個數字的狀態只有三種,分別為不存在,只有一個,有重復。因此,我們只需要2bits就可以對一個數字的狀態進行存儲了,假設我們設定一個數字不存在為00,存在一次01,存在兩次及其以上為11。那我們大概需要存儲空間幾十兆左右。
接下來的任務就是遍歷一次這2.5億個數字,如果對應的狀態位為00,則將其變為01;如果對應的狀態位為01,則將其變為11;如果為11,,對應的轉態位保持不變。
最后,我們將狀態位為01的進行統計,就得到了不重復的數字個數,時間復雜度為O(n)。
4. Bit-map應用之快速查詢
同樣,我們利用Bit-map也可以進行快速查詢,這種情況下對於一個數字只需要一個bit位就可以了,0表示不存在,1表示存在。假設上述的題目改為,如何快速判斷一個數字是夠存在於上述的2.5億個數字集合中。
同之前一樣,首先我們先對所有的數字進行一次遍歷,然后將相應的轉態位改為1。遍歷完以后就是查詢,由於我們的Bit-map采取的是連續存儲(整型數組形式,一個數組元素對應32bits),我們實際上是采用了一種分桶的思想。一個數組元素可以存儲32個狀態位,那將待查詢的數字除以32,定位到對應的數組元素(桶),然后再求余(%32),就可以定位到相應的狀態位。如果為1,則代表改數字存在;否則,該數字不存在。
5. Bit-map擴展——Bloom Filter(布隆過濾器)
當一個元素被加入集合中時,通過k各散列函數將這個元素映射成一個位數組中的k個點,並將這k個點全部置為1.
有一定的誤判率--在判斷一個元素是否屬於某個集合時,有可能會把不屬於這個集合的元素誤判為屬於這個集合.因此,它不適合那些"零誤判"的應用場合.在能容忍低誤判的應用場景下,布隆過濾器通過極少的誤判換區了存儲空間的極大節省.
Bloom Filter使用k個相互獨立的哈希函數(Hash Function),它們分別將集合中的每個元素映射到{1,…,m}的范圍中。對任意一個元素x,第i個哈希函數映射的位置hi(x)就會被置為1(1≤i≤k)。注:如果一個位置多次被置為1,那么只有第一次會起作用,后面幾次將沒有任何效果。
在判斷y是否屬於這個集合時,對y應用k次哈希函數,若所有hi(y)的位置都是1(1≤i≤k),就認為y是集合中的元素,否則就認為y不是集合中的元素。
6. 總結
使用Bit-map的思想,我們可以將存儲空間進行壓縮,而且可以對數字進行快速排序、去重和查詢的操作。Bloom Fliter是Bit-map思想的一種擴展,它可以在允許低錯誤率的場景下,大大地進行空間壓縮,是一種拿錯誤率換取空間的數據結構。
7. 應用
適用范圍:可進行數據的快速查找,判重,刪除,一般來說數據范圍是int的10倍以下
基本原理及要點:使用bit數組來表示某些元素是否存在,比如8位電話號碼
擴展:bloom filter可以看做是對bit-map的擴展
問題實例:
1、已知某個文件內包含一些電話號碼,每個號碼為8位數字,統計不同號碼的個數。
8位最多99 999 999,大概需要99m個bit,大概10幾M字節的內存即可。
2、在2.5億個整數中找出不重復的整數,內存不足以容納這2.5億個整數。
方案1:采用2-Bitmap(每個數分配2bit,00表示不存在,01表示出現一次,10表示多次,11無意義)進行,共需內存232*2bit=1GB內存,還可以接受。然后掃描這2.5億個整數,查看Bitmap中相對應位,如果是00變01,01變10,10保持不變。所描完事后,查看bitmap,把對應位是01的整數輸出即可。