BitMap算法
標簽: java
海量數據處理-BitMap算法
一、概述
本文將講述Bit-Map算法的相關原理,Bit-Map算法的一些利用場景,例如BitMap解決海量數據尋找重復、判斷個別元素是否在海量數據當中等問題.最后說說BitMap的特點已經在各個場景的使用性。
二、Bit-Map算法
先看看這樣的一個場景:給一臺普通PC,2G內存,要求處理一個包含40億個不重復并且沒有排過序的無符號的int整數,給出一個整數,問如果快速地判斷這個整數是否在文件40億個數據當中?
問題思考:
40億個int占(40億4)/1024/1024/1024 大概為14.9G左右,很明顯內存只有2G,放不下,因此不可能將這40億數據放到內存中計算。要快速的解決這個問題最好的方案就是將數據擱內存了,所以現在的問題就在如何在2G內存空間以內存儲著40億整數。一個int整數在java中是占4個字節的即要32bit位,如果能夠用一個bit位來標識一個int整數那么存儲空間將大大減少,算一下40億個int需要的內存空間為40億/8/1024/1024大概為476.83 mb,這樣的話我們完全可以將這40億個int數放到內存中進行處理。
具體思路:
1個int占4字節即48=32位,那么我們只需要申請一個int數組長度為 int tmp[1+N/32]即可存儲完這些數據,其中N代表要進行查找的總數,tmp中的每個元素在內存在占32位可以對應表示十進制數0~31,所以可得到BitMap表:
tmp[0]:可表示0~31
tmp[1]:可表示32~63
tmp[2]可表示64~95
…
那么接下來就看看十進制數如何轉換為對應的bit位:
假設這40億int數據為:6,3,8,32,36,…,那么具體的BitMap表示為:
那么怎么快速定位它的索引呢。如果找到它的索引號,又怎么定位它的位置呢。Index(N)代表N的索引號,Position(N)代表N的所在的位置號。
Index(N) = N/8 = N >> 3;
Position(N) = N%8 = N & 0x07;
public class BitMap {
//保存數據的
private byte[] bits;
//能夠存儲多少數據
private int capacity;
public BitMap(int capacity){
this.capacity = capacity;
//1bit能存儲8個數據,那么capacity數據需要多少個bit呢,capacity/8+1,右移3位相當于除以8
bits = new byte[(capacity >>3 )+1];
}
public void add(int num){
// num/8得到byte[]的index
int arrayIndex = num >> 3;
// num%8得到在byte[index]的位置
int position = num & 0x07;
//將1左移position后,那個位置自然就是1,然后和以前的數據做|,這樣,那個位置就替換成1了。
bits[arrayIndex] |= 1 << position;
}
public boolean contain(int num){
// num/8得到byte[]的index
int arrayIndex = num >> 3;
// num%8得到在byte[index]的位置
int position = num & 0x07;
//將1左移position后,那個位置自然就是1,然后和以前的數據做&,判斷是否為0即可
return (bits[arrayIndex] & (1 << position)) !=0;
}
public void clear(int num){
// num/8得到byte[]的index
int arrayIndex = num >> 3;
// num%8得到在byte[index]的位置
int position = num & 0x07;
//將1左移position后,那個位置自然就是1,然后對取反,再與當前值做&,即可清除當前的位置了.
bits[arrayIndex] &= ~(1 << position);
}
public static void main(String[] args) {
BitMap bitmap = new BitMap(100);
bitmap.add(7);
System.out.println("插入7成功");
boolean isexsit = bitmap.contain(7);
System.out.println("7是否存在:"+isexsit);
bitmap.clear(7);
isexsit = bitmap.contain(7);
System.out.println("7是否存在:"+isexsit);
}
}
每個byte存8個數字,相對于int類型來說,節省了32倍的存儲空間
存儲數據范圍,就上面的例子來說,上面bits數組的長度為13,那么總共可以存儲(13*8)104個數字,分別是(0~103)
上面的代碼并沒有擴容方法,超出范圍會報錯,
使用bit數組來表示某些元素是否存在,比如8位電話號碼.
缺點:
如果是比較特殊的數字,比如[1,100000000],那么就會浪費存儲空間,比如這個就必須要(100000000>>3)個字節
針對上面的缺點,谷歌所實現的EWAHCompressedBitmap對bitmap存儲空間做了一定的優化
相信的講解:http://www.sohu.com/a/166661005_479559
問題實例
1、在2.5億個整數中找出不重復的整數,注,內存不足以容納這2.5億個整數
解法一:采用2-Bitmap(每個數分配2bit,00表示不存在,01表示出現一次,10表示多次,11無意義)進行,共需內存2^32 * 2 bit=1 GB內存,還可以接受。然后掃描這2.5億個整數,查看Bitmap中相對應位,如果是00變01,01變10,10保持不變。所描完事后,查看bitmap,把對應位是01的整數輸出即可。
解法二:也可采用與第1題類似的方法,進行劃分小文件的方法。然后在小文件中找出不重復的整數,并排序。然后再進行歸并,注意去除重復的元素。”
2、給40億個不重復的unsigned int的整數,沒排過序的,然后再給一個數,如何快速判斷這個數是否在那40億個數當中?
解法一:可以用位圖/Bitmap的方法,申請512M的內存,一個bit位代表一個unsigned int值。讀入40億個數,設置相應的bit位,讀入要查詢的數,查看相應bit位是否為1,為1表示存在,為0表示不存在。
https://www.jianshu.com/p/6082a2f7df8e
https://wizardforcel.gitbooks.io/the-art-of-programming-by-july/content/06.07.html
http://blog.51cto.com/zengzhaozheng/1404108
http://blog.csdn.net/h348592532/article/details/45362661
https://www.cnblogs.com/protected/p/6626447.html
http://mp.weixin.qq.com/s?__biz=MzIxMjE5MTE1Nw==&mid=2653191272&idx=1&sn=9bbcd172b611b455ebfc4b7fb9a6a55e&chksm=8c990eb2bbee87a486c55572a36c577a48df395e13e74314846d221cbcfd364d44c280250234&scene=21#wechat_redire
智能推薦
BitMap算法的說明以及驗證
核心 1、什么是BitMap算法 2、BitMap的優缺點 3、BitMap的實現 4、BitMap 的比對 1、什么是BitMap算法 在大數據時代,我們如果將一個上億的整數文件來做排序或者查詢使用,這個就將面臨一個問題,內存不夠用,例如1億個整數的文件放入內存將會占用380MB(100000000*4/1024/1024)空間.如果是10億或者更多呢,這個將對內存是一個巨大的挑戰。為了解決這個...
Bitmap加載大圖優化之位圖重采樣與Bitmap緩存Lru算法分析
為什么要優化Bitmap 安卓加載圖片一般會用到ImageView控件,然后用setImageBitmap()、setImageResource()等方法指定要顯示的圖片,這些方法最終都會調用到BitmapFactory.decode()方法來生成一個Bitmap進行顯示,這樣加載一些小圖片沒什么問題,但連續加載大圖片的時候就會發生典型的OOM(Out Of ...
BitMap算法和C++ STL里面的bitset
今天看到大數據處理的BitMap算法,可以有效地對空間進行壓縮。 一、BitMap基本思想 在32位的機器上,一個int需要占據32位,而有時候這就是很大的空間浪費。比如沒有重復數字的計數排序的時候,假設數據范圍[0,1e8],則需要開辟數組int a[(int)1e8+1],a[i]表示i的出現的次數。這就需要大約400M的空間了。然而,由于數字不會重復,所以a[i]只會是0或1,那么32位的i...
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
猜你喜歡
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...
requests實現全自動PPT模板
http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...
Linux C系統編程-線程互斥鎖(四)
互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...
統計學習方法 - 樸素貝葉斯
引入問題:一機器在良好狀態生產合格產品幾率是 90%,在故障狀態生產合格產品幾率是 30%,機器良好的概率是 75%。若一日第一件產品是合格品,那么此日機器良好的概率是多少。 貝葉斯模型 生成模型與判別模型 判別模型,即要判斷這個東西到底是哪一類,也就是要求y,那就用給定的x去預測。 生成模型,是要生成一個模型,那就是誰根據什么生成了模型,誰就是類別y,根據的內容就是x 以上述例子,判斷一個生產出...