• 【算法】求多个数组中的交集(Java语言实现)


    简介:

      最近在工作中遇到一个问题,需要离线比较两张Mongodb表的差异:大小差异,相同的个数。

      所以,我将导出的bson文件转成了json文件(2G以上),一条记录正好是一行。

    问题:

      因此我将以上问题转换成了比较两个(本例考虑多个)超大数组的交集!所以要求时间复杂度、空间复杂度应该尽可能的低!

    降低内存:

      由于要将文件的每一行都读到内存里,如果行的长度比较大的话,内存肯定是不够的!

      所以我想到的办法是讲每一行压缩成md5编码。 String line = md5(line)。然后再将新的line读入内存。

      如此,通常1000万行记录读到内存里大概是800MB(这里有点忘了,反正大概是800MB~1GB)。

    (我使用的idea编辑器,跟eclipse可能在某些地方有点差别。另外,本例一字符数组为例,并且假设数组元素不重复!!!)

    MapReduce:

    /**
     * 这里以字符串数组为例
     * 采用mapreduce原理,生成一组以数组元素为key,相同元素的个数为value的中间键值对
     * 这里将mapreduce分开来写方便阅读,也可以写成一个函数
     * @param arrays
     */
    public static HashMap<String, Integer> mapReduce(final String[]... arrays) {
        HashMap<String, Integer> hashMap = new HashMap<>();
    
        // 不要看到两个for就以为时间复杂度为n^2,这里只是有多个数组参数而已
        for (String[] array : arrays) {
            for (String elem : array) {
                if (hashMap.containsKey(elem)) {
                    hashMap.put(elem, hashMap.get(elem) + 1);
                }
                else {
                    hashMap.put(elem, 1);
                }
            }
        }
    
        return reduce(hashMap, arrays.length);
    }

    Reduce:

    /**
     * 统计出相同元素个数正好是数组(参数)个数的元素(也就是每个数组中都有的元素)
     * 移除value不等于数组参数个数的键值对,并组成新的map
     * @param hashMap
     * @param arrayCount
     * @return
     */
    public static HashMap<String, Integer> reduce(HashMap<String, Integer> hashMap, final Integer arrayCount) {
        Iterator<String> iter = hashMap.keySet().iterator();
        String key;
    
        while(iter.hasNext()) {
            key = iter.next();
    
            if (!hashMap.get(key).equals(arrayCount)) {
           // 不能使用 hashMap.remove(key); 会出现异常, 见http://www.cnblogs.com/yrqiang/p/5344531.html iter.remove();
    } } return hashMap; }

    eg:

    /**
     * 本例假设同一数组中的元素不重复
     * @param args
     */
    public static void main(String[] args) {
        HashMap<String, Integer> hashMap = new HashMap<>();
    
        String[] arr1 = {"aa", "bb", "cc", "dd"};
        String[] arr2 = {"11", "bb", "cc", "dd", "ee"};
        String[] arr3 = {"22", "bb", "cc", "dd", "ee", "ff"};
    
        hashMap = mapReduce(arr1, arr2, arr3);
    
        System.out.println(hashMap);
        System.out.println(hashMap.size());
    }
  • 相关阅读:
    写在最前面
    Bzoj 2281 [Sdoi2011]黑白棋 题解
    bzoj3125: CITY 题解
    CDQZ 集训大总结
    CDQZ集训DAY10 日记
    CDQZ集训DAY9 日记
    CDQZ集训DAY7 日记
    CDQZ集训DAY6 日记
    CDQZ集训DAY5 日记
    CDQZ集训DAY4 日记
  • 原文地址:https://www.cnblogs.com/yrqiang/p/5316744.html
Copyright © 2020-2023  润新知