在一些資料量比較大的場景中,做一些查重、排序,一般的方法難以實現。資料量過大,會占用較大的記憶體,常用的處理方式有兩種:bitmap(位圖法)和布隆過濾。
本篇針對以下題目來看一下如何用位圖法來實現:10億個正整數,給定乙個數值,如何快速排定該數值是否在10億個正整數當中?
位圖法的思想類似於hash定址,首先初始化乙個int陣列,每個元素對應32位位元,將10億個元素分別讀入記憶體,對int陣列中的元素位元位進行標記,如果存在,標記為1即可。標記完之後,即可快速判定某個元素是否在10億個正整數當中,時間複雜度為o(1)。
需要多大的記憶體?10億個元素需要10億個位元位,10億/8/1024/1024 = 120 m,相比原來節省了 32 倍記憶體。
注意:這是最小使用記憶體。原因後面會介紹。
需要申請多大的陣列?每個int型別可標識32個整數,如下圖:array[0]:可表示0~31
array[1]:可表示32~63
array[2]可表示64~95
…陣列長度為10億/32 +1即可。
比如元素 119,如何確定其對應的陣列位元位 index ?
1)確定陣列 index:119/32 = 3.7,也就是第 4 個陣列元素,a[3] 的位置。
2)確定位元位 index:119%32 = 23,第23個位元位。
3)將位元位設定為1。
1)將位元位設定為1
將第28個位元位設定為1:
只需將 1 左移(31-28)位數,然後與原來的值進行或運算。
2)將位元位設定為0
將第28個位元位設定為0:
只需將 1 左移(31-28)位數,並進行非運算,然後與原來的值進行與運算。
3)判斷某一元素是否存在
判斷 28 位位元位是否有元素存在:
只需將 1 左移(31-28)位數,然後與原來的值進行與運算。只要與運算結果中有1,即表示元素存在。所以可以用執行結果是不為0作為元素是否存在依據。
public class bigmaptest
public void set1(int num)
public void set0(int num)
public boolean i***ist(int num)
/*** 將整型數字轉換為二進位制字串,一共32位,不捨棄前面的0
* @param number 整型數字
* @return 二進位制字串
*/private static string get32bitbinstring(int number)
return sbuilder.reverse().tostring();
}public static void main(string args) ;
bigmaptest bigmaptest = new bigmaptest(2234-1);
for (int i : arrays)
system.out.println(bigmaptest.i***ist(35));}}
優點:實現簡單。適合資料量比較大的場景。
缺點:占用記憶體。申請的陣列長度不好控制和最大的數值有關。當某個值特別大的情況下,對映的陣列超過申請的陣列容量,會出現下標越界。這也是上面提到的10億個元素占用120m是最小記憶體的原因,實際可能會大於這個記憶體。
LCD原理解析
硬體體系 3個部分 lcd液晶 屏 lcd驅動晶元 lcd控制器 整合在arm晶元內部 控制器 通過驅動晶元 控制液晶屏 液晶屏種類 stn gf tft tft 在嵌入式中較為常用 lcd控制器結構與模組 由17個可程式設計的暫存器組和一塊 256 16的調色盤內 存組成,通過這些暫存器,可以配置...
session原理解析
首先session跟cookies都是會會話進行跟蹤,session通過在伺服器端記錄資訊來記錄,cookies通過在客戶端記錄資訊來記錄。在此只對session進行分析 session是記錄在伺服器記憶體中的,每當乙個使用者通過瀏覽器第一次進行訪問時進行建立 需要注意只有訪問jsp,servlet...
Kerberos原理解析
kerberos這一名詞 於希臘神話 三個頭的狗 地獄之門守護者 系統設計上採用客戶端 伺服器結構與des加密技術,並且能夠進行相互認證,即客戶端和伺服器端均可對對方進行身份認證。可以用於防止竊聽 防止replay攻擊 保護資料完整性等場合,是一種應用對稱金鑰體制進行金鑰管理的系統。支援sso si...