zoukankan      html  css  js  c++  java
  • 【算法】求多个数组中的交集(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());
    }
  • 相关阅读:
    高精度计算模板
    P1108 低价购买 [DP][统计方案]
    POJ3349 Snowflake Snow Snowflakes [哈希]
    P1312 Mayan游戏 [深搜][模拟]
    P1378 油滴扩展[深搜]
    P1514 引水入城[搜索,线段覆盖]
    TYVJ1391 走廊泼水节
    【BZOJ1196】公路修建问题
    【BZOJ3624】免费道路
    【BZOJ2429】聪明的猴子
  • 原文地址:https://www.cnblogs.com/yrqiang/p/5316744.html
Copyright © 2011-2022 走看看