前言:
在分析MapReduce、Hive、Redis和Storm、Spark等工具实现分组Top n问题前,我们先看下java最原始实现Top的方法有哪些,为后面奠定些基础,这也是我要整理成一个系列的原因。
对于Top n问题,这里根据数据特点用合并法、快排过程法、大小顶堆和PriorityQueue固定队列四种方式来实现。
合并法:
数据描述:这种方法适用于几个数组有序的情况,来求Top k。
实现描述:采用Merge的方法,设定一个数组下标扫描位置记录临时数组和top结果数组,然后从临时数组记录下标开始遍历所有数组并比较大小,将最大值存入结果数组,最大值对应所在数组下标加一存入临时数组,以使其从下位开始遍历,时间复杂度为O(k*m)。(m:为数组的个数)。
具体实现:
package fjdm;
import java.util.ArrayList;
import java.util.List;
/**
* 已知几个递减有序的m个数组,求这几个数据前k大的数
* a[4,3,2,1],b[6,5,3,1] -> result[6,5,4]
* @author 张恩备
* @date 2016-11-25 上午10:57:03
*/
public class TopKByMerge{
public static int[] getTopK(List<List<Integer>>input,int k){
int index[]=new int[input.size()];//保存每个数组下标扫描的位置;
int result[]=new int[k];
for(int i=0;i<k;i++){
int max=Integer.MIN_VALUE;
int maxIndex=0;
for(int j=0;j<input.size();j++){
if(index[j]<input.get(j).size()){
if(max<input.get(j).get(index[j])){
max=input.get(j).get(index[j]);
maxIndex=j;
}
}
}
if(max==Integer.MIN_VALUE){
return result;
}
result[i]=max;
index[maxIndex]+=1;
}
return result;
}
public static void main(String[] args) {
List<Integer> a = new ArrayList<Integer>();
a.add(4);
a.add(3);
a.add(2);
a.add(1);
List<Integer> b = new ArrayList<Integer>();
b.add(6);
b.add(5);
b.add(3);
b.add(1);
List<List<Integer>> ab = new ArrayList<List<Integer>>();
ab.add(a);