zl程序教程

您现在的位置是:首页 >  大数据

当前栏目

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

数据 出现 元素 查找 重复 海量
2023-09-14 09:07:35 时间

 

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

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

理解:

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/zj/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();
    }
}