bitmap进行个数统计

昨天看了编程珠玑第一章的内容, 发现bitmap对于统计某一个范围内的整数个数效率很高, 就自己实现了一下:

这是原始的bitmap, 用于统计0~maxSize是否出现, 也可以用于排序

 3 public class BitMap
 4 {
 5     private int[] arr ;
 6     private final int mask = 0X1F ; //用于表示偏移量
 7     private final int shift = 5 ; //用于表示index处于arr的第几个
 8 
 9     public BitMap(int maxSize)
10     {
11         arr = new int[(maxSize-1)/32+1] ;
12     }
13 
14     //将index置1
15     public void set(int index)
16     {
17         //index>>5表示index在int中的第几个
18         //由于mask为16进制的11111, 所以index&mask的结果就是index在int中的位置
19         //或运算表示置1 , 与0相与表示置0
20         arr[index>>5] |= (1<<(index&mask)) ;
21     }
22 
23     //将index清零
24     public void clear(int index)
25     {
26         arr[index>>5] &= (~(1<<(index&mask))) ;
27     }
28 
29     //测试index是否为1
30     public boolean test(int index)
31     {
32         return (arr[index>>5] &= (1<<(index&mask))) != 0 ;
33     }
34 }

如果每个数字可能出现10次, 那么一个int型就可以表示8个元素, bitmap如下:

  1 /**
  2  * 每个数字最多出现10次
  3  */
  4 public class BitMap_FourBit
  5 {
  6     private int[] map ;
  7     private int shift = 3 ;
  8     private int mask = 0X7 ;
  9 
 10     public BitMap_FourBit(int N)
 11     {
 12         map = new int[(N-1)/4+1] ;
 13     }
 14 
 15     //加1
 16     public void add(int index)
 17     {
 18         int pos = index>>shift ;//除以8获取他在map中的位置
 19         int offset = offset(index) ;//获取在int中的偏移量
 20 
 21         int bit = get(pos , offset) ;
 22 
 23         clear(pos , offset);
 24         //System.out.println(bit);
 25         bit += (1<<offset) ; //加1
 26 
 27         map[pos] |= bit ;
 28     }
 29 
 30     //清0
 31     public void clear(int index)
 32     {
 33         int pos = pos(index) ;//除以8获取他在map中的位置
 34         int offset = offset(index) ;//获取偏移量
 35 
 36         clear(pos , offset);
 37     }
 38 
 39     //获取
 40     public int get(int index)
 41     {
 42         int pos = pos(index) ;
 43         int offset = offset(index) ;//获取偏移量
 44 
 45         return count(get(pos , offset)) ;
 46     }
 47 
 48     //除以4获取他在map中的位置
 49     private int pos(int index)
 50     {
 51         return index>>shift ;
 52     }
 53 
 54     //获取在int中位置
 55     private int offset(int index)
 56     {
 57         return (index&mask)<<2 ;
 58     }
 59 
 60     //统计个数
 61     private int count(int num)
 62     {
 63         int result = 0XF ;
 64 
 65         if((num & result) != 0)
 66             return result & num ;
 67 
 68         for(int i=1 ; i<=8 ; i++)
 69         {
 70             result <<= 4 ;
 71 
 72             if((num & result) != 0)
 73             {
 74                 result &= num ;
 75                 return result >> (4*i) ;
 76             }
 77         }
 78 
 79         return 0 ;
 80     }
 81 
 82     private int get(int pos , int offset)
 83     {
 84         int bit = 0XF<<offset ;
 85 
 86         return map[pos] & bit ;
 87     }
 88 
 89     private void clear(int pos , int offset)
 90     {
 91         int bit = 0XF<<offset ;
 92         map[pos] &= (~bit) ; //将原来的位置清0
 93     }
 94 
 95     public static void main(String[] args) {
 96         BitMap_FourBit bitMap_fourBit = new BitMap_FourBit(16) ;
 97 
 98         bitMap_fourBit.add(8) ;
 99         bitMap_fourBit.add(8) ;
100         bitMap_fourBit.add(9) ;
101         bitMap_fourBit.add(9) ;
102         bitMap_fourBit.add(9) ;
103         bitMap_fourBit.add(8) ;
104 
105         bitMap_fourBit.clear(9);
106 
107         System.out.println(bitMap_fourBit.get(8)) ;
108         System.out.println(bitMap_fourBit.get(9)) ;
109     }
110 }

 

posted @ 2016-08-24 10:26  iamzhoug37  阅读(1482)  评论(0编辑  收藏  举报