算法-海量数据处理

一、海量、无重复的数据排序–位图排序

适用条件:
1.只能用于整数的排序,或者可以准确映射到正整数(对象不同对应的正整数也不相同)的数据的排序。
2.不能处理重复的数据,重复的数据排序后只有一条(如果有这种需求可以在这个算法的基础上修改,给出现次数大于1的数据添加个计数器,然后存入Map中)
3.对于数据量极其大的数据处理可能还是比较占用空间,这种情况可配合多通道排序算法解决。

public class BitArray {
    private int[] bits = null;
    private int length;

    //用于设置或者提取int类型的数据的某一位(bit)的值时使用
    private final static int[] bitValue = {0x80000000,//10000000 00000000 00000000 00000000
            0x40000000,//01000000 00000000 00000000 00000000
            0x20000000,//00100000 00000000 00000000 00000000
            0x10000000,//00010000 00000000 00000000 00000000
            0x08000000,//00001000 00000000 00000000 00000000
            0x04000000,//00000100 00000000 00000000 00000000
            0x02000000,//00000010 00000000 00000000 00000000
            0x01000000,//00000001 00000000 00000000 00000000
            0x00800000,//00000000 10000000 00000000 00000000
            0x00400000,//00000000 01000000 00000000 00000000
            0x00200000,//00000000 00100000 00000000 00000000
            0x00100000,//00000000 00010000 00000000 00000000
            0x00080000,//00000000 00001000 00000000 00000000
            0x00040000,//00000000 00000100 00000000 00000000
            0x00020000,//00000000 00000010 00000000 00000000
            0x00010000,//00000000 00000001 00000000 00000000
            0x00008000,//00000000 00000000 10000000 00000000
            0x00004000,//00000000 00000000 01000000 00000000
            0x00002000,//00000000 00000000 00100000 00000000
            0x00001000,//00000000 00000000 00010000 00000000
            0x00000800,//00000000 00000000 00001000 00000000
            0x00000400,//00000000 00000000 00000100 00000000
            0x00000200,//00000000 00000000 00000010 00000000
            0x00000100,//00000000 00000000 00000001 00000000
            0x00000080,//00000000 00000000 00000000 10000000
            0x00000040,//00000000 00000000 00000000 01000000
            0x00000020,//00000000 00000000 00000000 00100000
            0x00000010,//00000000 00000000 00000000 00010000
            0x00000008,//00000000 00000000 00000000 00001000
            0x00000004,//00000000 00000000 00000000 00000100
            0x00000002,//00000000 00000000 00000000 00000010
            0x00000001 //00000000 00000000 00000000 00000001
    };

    public BitArray(int length) {
        if (length < 0) {
            throw new IllegalArgumentException("length必须大于等于零!");
        }
        //Java中整型为32位,所以数组长度为位长度/32。
        bits = new int[length / 32 + (length % 32 > 0 ? 1 : 0)];
        this.length = length;
    }

    //取index位的值
    public int getBit(int index) {
        if (index < 0 || index > length) {
            throw new IllegalArgumentException("length必须大于零小于" + length);
        }
        int intData = bits[index / 32];
        return (intData & bitValue[index % 32]) >>> (32 - index % 32 - 1);
    }

    //设置index位的值,只能为0或者1
    public void setBit(int index, int value) {
        if (index < 0 || index > length) {
            throw new IllegalArgumentException("length必须大于零小于" + length);
        }
        if (value != 1 && value != 0) {
            throw new IllegalArgumentException("value必须为0或者1");
        }
        int intData = bits[index / 32];
        if (value == 1) {
            //与移位后的1进行或运算,将指定的位,置为1,注意这里的定位。
            bits[index / 32] = intData | bitValue[index % 32];
        } else {
            //1移位到指定的位置后,取反,就是将0移动到指定的位置,
            //然后和原数进行与运算,就将指定的位置为0了,因为0和任何数相与,都变位0
            bits[index / 32] = intData & ~bitValue[index % 32];
        }
    }

    public int getLength() {
        return length;
    }
}
public class BitArrayTest {

    static BitArray bitArray = new BitArray(Utils.BIG_DATA_NUM);
    static String phoneNum;
    static int phoneNumAsInt;
    private static long startTime;

    public static void main(String[] args) throws IOException {
        Utils.generateDataNoMulti();
        BufferedReader bufferedReader = new BufferedReader(new FileReader(Utils.ORIGINAL_DATA_NO_MULTI_FILE_PATH));
        BufferedWriter writer = new BufferedWriter(new FileWriter(Utils.ROOT_PATH + "bit_sort.txt"));

        startTime = System.currentTimeMillis();
        //顺序读取所有数据
        while ((phoneNum = bufferedReader.readLine()) != null) {
            phoneNumAsInt = Integer.parseInt(phoneNum);
            bitArray.setBit(phoneNumAsInt, 1);
        }
        System.out.println("生成bit数组耗时:" + (System.currentTimeMillis() - startTime) + " ms ");

        startTime = System.currentTimeMillis();
        //遍历bit数组输出所有存在的号码
        for (int i = 0; i < bitArray.getLength(); i++) {
            if (bitArray.getBit(i) == 1) {
                writer.write(String.valueOf(i));
                writer.newLine();
            }
        }
        writer.flush();
        System.out.println("排序并输出耗时:" + (System.currentTimeMillis() - startTime) + " ms");
    }
}

测试结果

数据量=100000000
生成bit数组耗时:4676 ms 
排序并输出耗时:6383 ms
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值