所謂的bitmap就是用乙個bit位來標記某個元素所對應的value,而key即是該元素,由於bitmap使用了bit位來儲存資料,因此可以大大節省儲存空間。
基本思想:
這此我用乙個簡單的例子來詳細介紹bitmap演算法的原理。假設我們要對0-7內的5個元素(4,7,2,5,3)進行排序(這裡假設元素沒有重複)。我們可以使用bitmap演算法達到排序目的。要表示8個數(0-7),我們需要8個bit。
1.首先我們開闢乙個位元組(8bit)的空間,將這些空間的所有的bit位都設定為0
2.然後便利這5個元素,第乙個元素是4,因為下邊從0開始,因此我們把第五個bit的值設定為1
3.然後再處理剩下的四個元素,最終8個位元組的狀態如下圖
4.現在我們遍歷一次bit區域,把值為1的bit的位置輸出(2,3,4,5,7),這樣便達到了排序的目的
從上面的例子我們可以看出,bitmap演算法的思想還是比較簡單的,關鍵的問題是如何確定數值到bit區域的對映圖
map對映:
假設需要排序或則查詢的數的總數n=100000000,bitmap中1bit代表乙個數字,那麼n個數需要n個bit,在32位機器上,int是4位元組32bit,所以需要(n/32)個int的空間。所以我們需要申請記憶體空間的大小為int a[1 + n/32]。
其中a[0]的bit對映數值0-31,依次類推:
a[0]-----------------------------> 0-31
a[1]------------------------------> 32-63
a[2]-------------------------------> 64-95
a[3]--------------------------------> 96-127
那麼數值如何對映到對應的bit位,下面介紹用位移將數值轉換為對應的bit位:
1.求數值在對應陣列a中的下標
數值0-31對映到a[0]中,32-63對映到a[1]中,64-95對映到a[2]中………,使用數學歸納分析得出結論:對於乙個數值n,其在陣列a中的下標為:a[n/32]
2.求出十進位制數在對應數a[i]中的下標
例如十進位制數1在a[0]的bit下標是1,十進位制數31在a[0]中的bit下標為31,十進位制數32在a[1]中下標為0。 在十進位制0-31就對應0-31,而32-63則對應也是0-31,即給定乙個數n可以通過模32求得在對應陣列a[i]中的下標:
a[n/32] |= 1 << n % 32
移位操作:
a[n>>5] |= 1 << (n & 0x1f)
n & 0x1f 保留n的後五位 相當於 n % 32 求十進位制數在陣列a[i]中的下標
**實現:
public class bitmap
// 判斷所在的bit為是否為1
public boolean exits(int n)
public void display(int row)
system.out.println("a["+i+"]" + list);}}
public static void main(string args);
bitmap map = new bitmap();
for(int i=0;i應用範圍:
可以運用在快速查詢、去重、排序、壓縮資料等。
原文:
其他文章推薦:
KMP演算法詳講
一 簡單匹配演算法 先來看乙個簡單匹配演算法的函式 int index bf char s char t int pos else j nextval j 子串移動到第nextval j 個字元和主串相應字元比較 下面是我寫的kmp模式匹配程式,各位可以測試一下。include include in...
Floyd Warshall演算法DP流程詳解
floyd warshall演算法,簡稱floyd演算法,用於求解任意兩點間的最短距離,時間複雜度為o n 3 我們平時所見的floyd演算法的一般形式如下 1void floyd 注意下第6行這個地方,如果dist i k 或者dist k j 不存在,程式中用乙個很大的數代替。最好寫成if di...
Spark 中LocalKmeans演算法詳解
kmeans演算法的具體思想這裡省略。kmeans演算法實現步驟一般如下 1 從d 中隨機取 k個元素,作為 k個簇的各自的中心,或者隨機生成k個中心元素。2 分別計算剩下的元素到 k個簇中心的相異度,將這些元素分別劃歸到相異度最低的簇。3 根據聚類結果,重新計算 k個簇各自的中心,計算方法是取簇中...