用bitmap节省存储空间

bitmap,即是用bit和存储数据组成map,这里以一个bit对应一个数据,也就是bit作为key,对应的数据则是value.这样一个很大的数据,我们用一个bit来存储,就节省了很大的存储空间。我们可以用一个例子来说明:
对5亿个int型数据进行排重。
首先,int型数据是32bit,那么5亿个int即使是排重以后,最多可占用2^32*4byte,也就是16G,我们的电脑内存当然是不够的。我们就可以试着用bitmap来解决问题。
如果用bit来标记int,那么存储空间要缩小到原来的32倍,只需0.5G。具体实现时,由于java中最小数据类型是byte,0.5G=2^32bit=2^29byte,我们可以先建立一个长度为2^29的byte型数组
byte[] b = new byte[2^29];
对这5亿个数据依次进行如下处理
val = n/8;
rem = n%8;
把b中第val个元素的第rem-1位用1表示相应的value存在。当处理完这5亿个数据后,分别找出数组b中2^32个bit中,第几个是1,那么第几个1对应的位置就是相应的数据。

用这个方法,我们可以解决对容量很大的两个整数集求交集的问题。当A、B两个整数集都很大时,要求它们的交集,我们用以下代码表示:
首先建立一个长度为2^32的String型数组(这里为了简便,直接用字符串表示出0、1串)从A、B两个文档中读取两个整数集
[img]http://dl2.iteye.com/upload/attachment/0090/1439/ea2220e5-43f8-3fff-98f2-aa757d206e2f.png[/img]


/**
* 从文件中读取数据,并把数据存入byte型数组中
* @param str
* @return
*/
public String[] createA(String str) {
String[] a = new String[max];
for(int i=0;i<max;i++){
a[i] = "00000000";
}
File file = new File(str);
try {
file.createNewFile();
FileReader r = new FileReader(file);
long len = file.length();
//以字符串的形式把整数读取过来
char c = (char) r.read();
int n = 0;
while(n<len){
String num = "";
while(c!=' '&&c!='\n'){
num = num+c;
c = (char) r.read();
n=n+1;
}
int i = Integer.parseInt(num);
System.out.println(i);
//把i存到数组中
toByte(i,a);
n++;
c = (char) r.read();
}

} catch (IOException e) {
e.printStackTrace();
}
return a;
}

/**
* 把int型i存入数组
* @param i
* @param a
*/
public void toByte(int i,String[] a){
int value = i/8;
int remain = i%8;
char[] c = a[value].toCharArray();
c[remain] = '1';
a[value]="";
for(int j=0;j<8;j++){
a[value]=a[value]+c[j];
}
}

再对两个数组进行比较,把相同的数据存入文档C
/**
* 比较获得两个数组中的整数,并把他们共同有的整数写到文件C里面
* @param a
* @param b
*/
public void compare(String[] a,String[] b){
File file = new File("d:/C.txt");
try {
file.createNewFile();
FileWriter writer = new FileWriter(file);
String aa;
String bb;
for(int i=0;i<max;i++){
System.out.println("a["+i+"]="+a[i]+","+"b["+i+"]="+b[i]);
aa = a[i];
bb = b[i];
for(int j=0;j<8;j++){
char a0 = aa.charAt(j);
char b0 = bb.charAt(j);
if(a0=='1'&&b0=='1'){
System.out.println("当有两个数相等时");
int v = i*8+j+1;
System.out.println("交集中有+++++++++++++++++"+v);
writer.write(v+" ");
}
}

}
writer.flush();
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}



[img]http://dl2.iteye.com/upload/attachment/0090/1441/fc9e3bf1-187a-33bb-89ac-c57d3f404d82.png[/img]
当然,这里为了简便,使用了字符串,如果对位操作很熟悉的同学,也可以通过位操作来实现。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值