【算法】求多个数组中的交集(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());
}
【算法】求多个数组中的交集(Java语言实现)的更多相关文章
- SQL Server 2008 R2——查找最小nIndex,nIndex存在而nIndex+1不存在 求最小连续数组中的最大值
=================================版权声明================================= 版权声明:原创文章 谢绝转载 请通过右侧公告中的“联系邮 ...
- Problem N: 求二维数组中的鞍点【数组】
Problem N: 求二维数组中的鞍点[数组] Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 2764 Solved: 1728[Submit][S ...
- 求一无序数组中第n大的数字 - 快速选择算法
逛别人博客的时候,偶然看到这一算法题,顺便用C++实现了一下. 最朴素的解法就是先对数组进行排序,返回第n个数即可.. 下面代码中用的是快速选择算法(不晓得这名字对不对) #include <v ...
- 【算法30】从数组中选择k组长度为m的子数组,要求其和最小
原题链接:codeforce 267 Div2 C 问题描述: 给定长度为n的数组a[],从中选择k个长度为m的子数组,要求和最大. 形式描述为:选择$k$个子数组[$l_1$, $r_1$], [$ ...
- c语言经典算法——查找一个整数数组中第二大数
题目: 实现一个函数,查找一个整数数组中第二大数. 算法思想: 设置两个变量max1和max2,用来保存最大数和第二大数,然后将数组剩余的数依次与这两个数比较,如果这个数a比max1大,则先将max1 ...
- 窥探算法之美妙——寻找数组中最小的K个数&python中巧用最大堆
原文发表在我的博客主页,转载请注明出处 前言 不论是小算法或者大系统,堆一直是某种场景下程序员比较亲睐的数据结构,而在python中,由于数据结构的极其灵活性,list,tuple, dict在很多情 ...
- Task 4.5 求二维数组中的最大连通子数组之和
任务:输入一个二维整形数组,数组里有正数也有负数. 求所有子数组的和的最大值.要求时间复杂度为O(n). 1.设计思想:因为用之前的解决子数组最大和的问题的思路一直没能解决这个问题,后来看到同学使用将 ...
- 求一个number数组中的最大值和最小值的差
<!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content ...
- [PHP] 算法-二位有序数组中查找的PHP实现
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 1.二 ...
随机推荐
- netbeans字体与颜色配置模板相关网站
NetBeans Themes -Color Schemes of the NetBeans IDE NetBeans ThemeBuilder
- 【leetcode边做边学】二分查找应用
很多其它请关注我的HEXO博客:http://jasonding1354.github.io/ 简书主页:http://www.jianshu.com/users/2bd9b48f6ea8/lates ...
- 【Linux学习】Ubuntu下嵌入式交叉编译环境arm-linux-gcc搭建
(1)首先选择一个路径用来存放arm-linux-gcc.我选用的是/home/book,并在以下建立一个目录arm-linux-gcc. (2)利用cp EABI-4.3.3_Emdedsky_20 ...
- TASKKILL命令使用方法
TASKKILL [/S system [/U username [/P [password]]]] { [/FI filter] [/PID processid | /IM ima ...
- 用ssh建立机器之间的信任机制
继续整理以前的博客,第二弹:用ssh建立机器之间的信任机制 #!/bin/bash #需要远程添加信任机制的机器 REMOTE[]=db-XXX-XXX1.db01 REMOTE[]=db-XXX-X ...
- JDK,JRE,JVM区别与联系(转)
JDK : JavaDevelopment ToolKit(Java开发工具包).JDK是整个JAVA的核心,包括了Java运行环境(Java Runtime Envirnment),一堆Java工具 ...
- BUAA 更大公约数
题目链接 给一个n*m的矩阵, 删除里面的一行一列, 使得剩下的数的最大公约数最大. 一个格子(x,y), 先预处理出(1,1)到这个格子的内所有数的最大公约数, 同理处理出(1, m), (n, m ...
- 利用python进行数据分析之数据加载存储与文件格式
在开始学习之前,我们需要安装pandas模块.由于我安装的python的版本是2.7,故我们在https://pypi.python.org/pypi/pandas/0.16.2/#downloads ...
- Unix/Linux笔记全集
1:Unix/Linux操作系统概述 要求:理解应用软件和操作系统的区别,掌握系统的Kernel(核心)和shell(外壳)之间的关系以及各自的作用 Solaris:Solaris 是Sun Micr ...
- Java的序列化
1.为啥需要序列化 在Java编程时,一个类被实例化以后,Java虚拟机使得对象处理生存状态,但是当虚拟机关闭后,对象就不复存在了,所以一个对象的生存期不会超过JVM的工作时间,那么如何才能让对象持续 ...