位映射

 前些天讨论了位映射的内容,一个具体的例子就对于M个int的排重(就是排除重复的数),M至少大于内存的大小,这样我们就不能把所有的数直接放到数组里面。我们可以令M等于10亿,以32位的电脑为例,其最大可使用内存是4G,也就是2^32个字节,一个int占四个字节,能表示从2^32个数,所以内存是无法将这些数全部放进去的。但是用位映射的方式,我们可以用较小的位来表示int,也就是说我们可以用1位来表示一个int,也就是说原先需要4G容量的,现在我们只需要512M就可以满足要求。(不过这样做也是很暴力!)
 但是在java中我们是不能直接对为进行操作的,能操作的最小的是byte(即八位),所以我们需要一个大小为2^29的数组,当某个数出现后我们将其对应的位写为1,
 byte[] b = new byte[2^29];
 数组的每一个元素对应8个int对于每一个整数,首先读取该整数,做一下操作
 m = num / 8;
 n = num % 8;
 m为该数在数组中的位置,n为在8bit中的位置。
 b[m] = (byte) (b[m] | (1 << n));
 先对左移n位在对与数组进行或操作,这样就将数存放到数组里面,读取数组中的内容相当于是逆过程
 
 for (int i = 0; i < b.length; i++) {
   for (int j = 0; j < 8; j++) {
    if (!((b[i]&(1<<j))==0)) {  //用1与上数组元素的每一位
     int oriNum = b[i]*8+i;
     System.out.println(oriNum);
    }
   }
  }
  
 读取内容的时候先循环遍历数组的内容,然后用1与上数组元素的每一位,如果该位上为1,则说明该数存在,则将其输出,

猜你喜欢

转载自raidyue.iteye.com/blog/1781955
今日推荐