用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两个文档中读取两个整数集



/**
	 * 从文件中读取数据,并把数据存入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();
		}
	}

	



当然,这里为了简便,使用了字符串,如果对位操作很熟悉的同学,也可以通过位操作来实现。

猜你喜欢

转载自1075345532.iteye.com/blog/1956010