數據結構與算法-BitMap和RoaringBitmap


Bitmap

 bitmap(位圖)的數據結構

Java中的BitSet數據結構

01.Java中Bitset的使用
  Java中原生的bitmap的實現: BitSet
  BitSet 一個Bitset類創建一種特殊類型的數組來保存位值。BitSet中數組大小會隨需要增加
    BitSet定義了兩個構造方法:  BitSet()  BitSet(int size)
	BitSet的底層實現是使用long數組作為內部存儲結構的
  變為Bitset
    cardinality( ) 返回此 BitSet 中設置為 true 的位數
	                    //就是BitSet中存放的有效位的個數,如果有重復運算會進行自動去重
    length()       返回此 BitSet 的"邏輯大小": BitSet 中最高設置位的索引加 1
    size( )        返回此 BitSet 表示位值時實際使用空間的位數
	                (即通過使用此BitSet表示位來分配給實際位數的內存)。128bit
   說明:  null 參數傳遞給 BitSet 中的任何方法都將導致 NullPointerException
基本操作
  Bitmap的基本操作有: set()  clear()  flip()
    初始化一個bitset,指定大小。
    清空bitset。
    反轉某一指定位。
    設置某一指定位。
    獲取某一位的狀態。
    當前bitset的bit總位數。
	邏輯計算   and or andNot  xor
   排序: 按照順序循環取出在BitSet存在的數,以此達到排序的目的
02. Bitset 源碼:
   recalculateWordsInUse();  wordsInUse 是檢查當前的long數組中,實際使用的long的個數
   checkInvariants();
  這兩個函數,是對bitset的內部狀態進行維護和檢查的函

Roaringbitmap

container是RBM新創造的概念:
    ArrayContainer   BitmapContainer  RunContainer
具體的實現
  開源工具類 JavaEWAH 或者 RoaringBitmap
  開源工具實現-- EWAHCompressedBitmap(谷歌對Bitmap的實現)
    <dependency>
        <groupId>com.googlecode.javaewah</groupId>
        <artifactId>JavaEWAH</artifactId>
        <version>1.1.7</version>
    </dependency>
  開源工具實現
  	<dependency>
        <groupId>org.roaringbitmap</groupId>
        <artifactId>RoaringBitmap</artifactId>
        <version>0.8.1</version>
    </dependency>
1.Roaringbitmap  
  主要的操作 org.roaringbitmap.RoaringBitmap
      主要使用 add remove  bitmapOf()
              and or xor                   
   // 向r1中添加1、2、3、1000四個數字
      RoaringBitmap r1 = RoaringBitmap.bitmapOf(1, 2, 3, 1000);  
  2.  位圖位於內存映射文件中,則可以改用 org.roaringbitmap.buffer 包	
ImmutableRoaringBitmap 和 MutableRoaringBitmap
  public class MutableRoaringBitmap extends ImmutableRoaringBitmap 
	          implements Cloneable, Serializable, Iterable<Integer>, Externalizable,
	          BitmapDataProvider, AppendableStorage<MappeableContainer> {}
從ByteBuffer創建ImmutableRoaringBitmap
	    ByteArrayOutputStream bos = new ByteArrayOutputStream()
		ByteBuffer bb = ByteBuffer.wrap(bos.toByteArray());
		ImmutableRoaringBitmap rrback1 = new ImmutableRoaringBitmap(bb);   
 3.,RoaringBitmap處理的是int類型的數據,但是在實際中我們使用的都是long類型的,可以使用Roaring64NavigableMap。
   Roaring64NavigableMap
  Roaring64NavigableMap也是使用拆分模式,將一個long類型數據,拆分為高32位與低32位,
   高32位代表索引,低32位存儲到對應RoaringBitmap中,其內部是一個TreeMap類型的結構,會按照signed或者unsigned進行排序,key代表高32位,value代表對應的RoaringBitmap。 

應用場景

  01.給定含有40億個不重復的位於[0, 4294967295]區間內的整數的集合,如何快速判定某個數是否在該集合內?
      正常Java int類型存儲 2^32*4*8/8/2^10/2^10/2^10 = 16GB
     一個bit位代表一個整數是否存在,可以計算出所占用的大小就是  2^32*1/8/2^10/2^10 = 512M
  02.在3億個整數中找出不重復的整數
  03. 已知某個文件內包含一些電話號碼,每個號碼為8位數字,統計不同號碼的個數

參考:

 BitMap的原理和實現 https://www.cnblogs.com/myseries/p/10880641.html
 https://github.com/RoaringBitmap/RoaringBitmap 
 Python: 實現bitmap數據結構 https://my.oschina.net/goal/blog/200347
 RoaringBitmap精確去重 https://blog.csdn.net/lao000bei/article/details/105725579


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM