海量数据中查找出重复出现的元素(位图法)

 

位图可以用来排序,去重等。

但下面的位图法一般用来做正整数的排序,去重;若有负整数,可以再新建一个队列专门存负整数,先转成正整数去比较,存在这个负整数队列。

理解:

8位整数可以表示的最大十进制数值为99999999。如果每个数字对应于位图中一个bit位,那么存储8位整数大约需要99MB。因为1B=8bit,所以99Mbit折合成内存为99/8=12.375MB的内存,即可以只用12.375MB的内存表示所有的8位数电话号码的内容

 

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import com.google.common.collect.Lists;

/**
* 位图
*/
public class Weitu {

private static final int BITSPERWORD = 32;// 整数位数

private static final int SHIFT = 5;

private static final byte MASK = 0x1F;//5位遮蔽 0B11111

private static final int N = 1000;

private static int[] a = new int[1 + N / BITSPERWORD];

private static List<String> list = new ArrayList<String>(1 + N / BITSPERWORD);

public static void main(String[] args) throws Exception {
Weitu tu = new Weitu();
// tu.readFile("/Users/zj/aa1.txt");
tu.readFile("C:/Users/ZHENGJIE2/Desktop/aa1.txt");

for (int i = 0; i < list.size(); i++) {
tu.set(Integer.parseInt(list.get(i)));
}

List<Integer> resultList = Lists.newArrayList();
for (int i = 0, length = a.length; i < length; i++) {
if (a[i] != 0) {
for (int j = 0; j < (1 << SHIFT); j++) {
if (((1 << j) & a[i]) != 0) {
resultList.add(i * (1 << SHIFT) + j);
}
}
}
}

for (Integer xx : resultList) {
System.out.println(xx);
}
System.out.println((1 << 31) - 1);
System.out.println(Integer.MAX_VALUE);
}

// 置a[i>>SHIFT]的第(i & MASK)位为1,也就是位数组的第i位为1
public void set(int i) {
if (test(i)) {
System.err.println(i);
}
a[i >> SHIFT] |= (1 << (i & MASK));
}

// 置a[i>>SHIFT]的第(i & MASK)位为0,也就是位数组的第i位为0
public void clr(int i) {
a[i >> SHIFT] &= ~(1 << (i & MASK));
}

public int test11(int i) {
return a[i >> SHIFT] & (1 << (i & MASK));
}

// 测试位数组的第i位是否为1 (可以用作重复问题)
public static boolean test(int i) {
return (a[i >> SHIFT] & (1 << (i & MASK))) == (1 << (i & MASK));
}

public void readFile(String filePath) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath)));
String len;
while ((len = br.readLine()) != null) {
list.add(len);
}
br.close();
}
}

转载于:https://www.cnblogs.com/fanguangdexiaoyuer/p/8258697.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值