成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

10億數據如何快速找到某個數 | 經典算法BitMap詳解

大數據 算法
有一個無序有界int數組{1,2,5,7},初步估計占用內存44=16字節,因為只有4個數,很容易,可以很快找到需要的數。但是假如有10億個這樣的數呢,10億個不重復并且沒有排過序的無符號的int整數,給出一個整數,找出給定的某個數,你該如何操作?

前言

  • BitMap從字面的意思,很多人認為是位圖,其實準確的來說,翻譯成基于位的映射,怎么理解呢?

問題引入

有一個無序有界int數組{1,2,5,7},初步估計占用內存44=16字節,因為只有4個數,很容易,可以很快找到需要的數。但是假如有10億個這樣的數呢,10億個不重復并且沒有排過序的無符號的int整數,給出一個整數,找出給定的某個數,你該如何操作?

需求分析:Int類型在Java中的存儲占用4個Byte,32Bit。10億4/(102410241024)=3.72G左右。如果這樣的一個大的數據做查找和排序,那估計內存也崩潰了,有人說,這些數據可以不用一次性加載,那就是要存盤了,存盤必然消耗IO。我們提倡的是高性能,這個方案直接不考慮。

[[330308]]

問題分析

如果用BitMap思想來解決的話,就好很多,那么BitMap是怎么解決的啊,如下:

一個byte是占8個bit,如果每一個bit的值就是有或者沒有,也就是二進制的0或者1,如果用bit的位置代表數組值有還是沒有,那么0代表該數值沒有出現過,1代表該數組值出現過。不也能描述數據了嗎?具體如下圖: 

10億數據如何快速找到某個數 | 經典算法BitMap詳解

是不是很神奇,那么現在假如10億的數據所需的空間就是3.72G/32了吧,一個占用32bit的數據現在只占用了1bit,節省了不少的空間,排序就更不用說了,一切顯得那么順利。這樣的數據之間沒有關聯性,要是讀取的,你可以用多線程的方式去讀取。時間復雜度方面也是O(Max/n),其中Max為byte[]數組的大小,n為線程大小。

三、應用與代碼

如果BitMap僅僅是這個特點,我覺得還不是它的優雅的地方,接下來繼續欣賞它的魅力所在。下面的計算思想其實就是針對bit的邏輯運算得到,類似這種邏輯運算的應用場景可以用于權限計算之中。

再看代碼之前,我們先搞清楚一個問題,一個數怎么快速定位它的索引號,也就是說搞清楚byte[index]的index是多少,position是哪一位。舉個例子吧,例如add(14)。14已經超出byte[0]的映射范圍,在byte[1]范圍之類。那么怎么快速定位它的索引呢。如果找到它的索引號,又怎么定位它的位置呢。Index(N)代表N的索引號,Position(N)代表N的所在的位置號。

  • Index(N) = N/8 = N >> 3;
  • Position(N) = N%8 = N & 0x07;

(1) add(int num)

你要向bitmap里add數據該怎么辦呢,不用擔心,很簡單,也很神奇。上面已經分析了,add的目的是為了將所在的位置從0變成1.其他位置不變. 

10億數據如何快速找到某個數 | 經典算法BitMap詳解

實例代碼:

  1. public void add(int num){ 
  2.         // num/8得到byte[]的index 
  3.         int arrayIndex = num >> 3;  
  4.          
  5.         // num%8得到在byte[index]的位置 
  6.         int position = num & 0x07;  
  7.          
  8.         //將1左移position后,那個位置自然就是1,然后和以前的數據做|,這樣,那個位置就替換成1了。 
  9.         bits[arrayIndex] |= 1 << position;  
  10.     } 

(2) clear(int num)

對1進行左移,然后取反,最后與byte[index]作與操作。 

10億數據如何快速找到某個數 | 經典算法BitMap詳解

實例代碼:

  1. public void clear(int num){ 
  2.         // num/8得到byte[]的index 
  3.         int arrayIndex = num >> 3;  
  4.          
  5.         // num%8得到在byte[index]的位置 
  6.         int position = num & 0x07;  
  7.          
  8.         //將1左移position后,那個位置自然就是1,然后對取反,再與當前值做&,即可清除當前的位置了. 
  9.         bits[arrayIndex] &= ~(1 << position);  
  10.  
  11.     } 

(3) contain(int num) 

10億數據如何快速找到某個數 | 經典算法BitMap詳解

實例代碼:

  1. public boolean contain(int num){ 
  2.        // num/8得到byte[]的index 
  3.        int arrayIndex = num >> 3;  
  4.         
  5.        // num%8得到在byte[index]的位置 
  6.        int position = num & 0x07;  
  7.         
  8.        //將1左移position后,那個位置自然就是1,然后和以前的數據做&,判斷是否為0即可 
  9.        return (bits[arrayIndex] & (1 << position)) !=0;  
  10.    } 

全部代碼如下:

  1. public class BitMap { 
  2.     //保存數據的 
  3.     private byte[] bits; 
  4.      
  5.     //能夠存儲多少數據 
  6.     private int capacity; 
  7.      
  8.      
  9.     public BitMap(int capacity){ 
  10.         this.capacity = capacity; 
  11.          
  12.         //1bit能存儲8個數據,那么capacity數據需要多少個bit呢,capacity/8+1,右移3位相當于除以8 
  13.         bits = new byte[(capacity >>3 )+1]; 
  14.     } 
  15.      
  16.     public void add(int num){ 
  17.         // num/8得到byte[]的index 
  18.         int arrayIndex = num >> 3;  
  19.          
  20.         // num%8得到在byte[index]的位置 
  21.         int position = num & 0x07;  
  22.          
  23.         //將1左移position后,那個位置自然就是1,然后和以前的數據做|,這樣,那個位置就替換成1了。 
  24.         bits[arrayIndex] |= 1 << position;  
  25.     } 
  26.      
  27.     public boolean contain(int num){ 
  28.         // num/8得到byte[]的index 
  29.         int arrayIndex = num >> 3;  
  30.          
  31.         // num%8得到在byte[index]的位置 
  32.         int position = num & 0x07;  
  33.          
  34.         //將1左移position后,那個位置自然就是1,然后和以前的數據做&,判斷是否為0即可 
  35.         return (bits[arrayIndex] & (1 << position)) !=0;  
  36.     } 
  37.      
  38.     public void clear(int num){ 
  39.         // num/8得到byte[]的index 
  40.         int arrayIndex = num >> 3;  
  41.          
  42.         // num%8得到在byte[index]的位置 
  43.         int position = num & 0x07;  
  44.          
  45.         //將1左移position后,那個位置自然就是1,然后對取反,再與當前值做&,即可清除當前的位置了. 
  46.         bits[arrayIndex] &= ~(1 << position);  
  47.  
  48.     } 
  49.      
  50.     public static void main(String[] args) { 
  51.         BitMap bitmap = new BitMap(100); 
  52.         bitmap.add(7); 
  53.         System.out.println("插入7成功"); 
  54.          
  55.         boolean isexsit = bitmap.contain(7); 
  56.         System.out.println("7是否存在:"+isexsit); 
  57.          
  58.         bitmap.clear(7); 
  59.         isexsit = bitmap.contain(7); 
  60.         System.out.println("7是否存在:"+isexsit); 
  61.     } 

總結:

Bitmap典型的應用場景為:大量數據的快速排序、查找、去重

其被廣泛用于數據庫和搜索引擎中,通過利用位級并行,它們可以顯著加快查詢速度。

但是,位圖索引會占用大量的內存,因此我們會更喜歡壓縮位圖索引。

以上為全部內容。

 

責任編輯:未麗燕 來源: 今日頭條
相關推薦

2024-07-04 13:42:12

2025-05-12 01:55:00

MySQL存儲數據

2025-06-26 08:22:03

2025-02-21 08:20:33

2019-08-20 00:39:28

數據存儲層冗余

2024-08-13 14:10:49

2024-06-03 06:45:18

2024-02-19 11:49:23

JavaBitMap類型

2024-03-06 09:22:23

C#數據庫判重

2023-09-04 10:10:47

插件頁面元素

2015-04-03 12:47:14

NoSQL開源非關系型數據庫

2022-11-16 13:16:23

微軟Windows

2019-03-05 10:16:54

數據分區表SQLserver

2021-01-26 05:33:07

排序算法快速

2024-04-15 08:30:53

MySQLORM框架

2020-02-20 14:20:28

Windows 10啟動程序加載時間

2021-02-05 10:58:28

數據存儲架構

2024-07-02 08:28:17

開源代碼社區

2021-02-03 10:43:54

Linux系統磁盤

2019-05-05 09:28:59

架構數據查詢
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品一区二区在线 | 国产中文字幕在线观看 | 亚洲中国字幕 | 国产日韩精品一区二区三区 | 无码一区二区三区视频 | 免费黄色成人 | 精品国产乱码久久久久久闺蜜 | 一级免费黄色 | 免费的av | 日韩三级 | 日韩精品一区二区三区中文在线 | av天天干| 精品国产91乱码一区二区三区 | 亚洲成人精品在线 | 九七午夜剧场福利写真 | 久久久久久久久综合 | 久久久久91 | 日韩成人在线视频 | 国产精品99久久久久久久久久久久 | 伊人久久综合 | 久久精品亚洲欧美日韩久久 | 国产精品一区在线播放 | 久久天天躁狠狠躁夜夜躁2014 | 免费一级欧美在线观看视频 | 精品久久久网站 | 国产高清一区二区 | 日韩精品无码一区二区三区 | 亚洲欧美日韩久久 | 亚洲视频免费在线观看 | 精品国产乱码久久久久久丨区2区 | 亚洲第一在线 | 国产精品日韩欧美 | 天天插天天舔 | 蜜桃视频在线观看免费视频网站www | 亚洲九色| 精品欧美一区二区三区久久久小说 | 国产视频二区在线观看 | 国产精品视频专区 | 特黄色毛片 | 中文字幕在线免费观看 | 欧美一区二区在线观看 |