昨天看了编程珠玑第一章的内容, 发现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 }