假设您从“流”源读取数据项和相关分数(即不可能进行随机访问或多次传递)。
什么是在任何时候只保留内存中迄今为止遇到的权重最低的那些元素的最佳方法。我会对“Java”的做法感兴趣,成语越短越好,而不是算法(“使用搜索树,插入新元素,如果超出大小则删除最大的元素”)。
下面是我想出的解决方案,但是我觉得有点冗长,而且有些行为可能是出乎意料的(不同分数的同一个项目可能会保留多次,而相同分数的相同项目只保留一次) . 我也觉得应该为此存在一些东西。
import java.util.AbstractMap.SimpleEntry;
import java.util.Map.Entry;
import java.util.Comparator;
import java.util.TreeSet;
/**
* Stores the n smallest (by score) elements only.
*/
public class TopN<T extends Comparable<T>> {
private TreeSet<Entry<T, Double>> elements;
private int n;
public TopN(int n) {
this.n = n;
this.elements = new TreeSet<Entry<T, Double>>(
new Comparator<Entry<T, Double>>() {
@Override
public int compare(Entry<T, Double> o1, Entry<T, Double> o2) {
if (o1.getValue() > o2.getValue()) return 1;
if (o1.getValue() < o2.getValue()) return -1;
return o1.getKey() == null ? 1 : o1.getKey().compareTo(o2.getKey());
}
});
}
/**
* Adds the element if the score is lower than the n-th smallest score.
*/
public void add(T element, double score) {
Entry<T, Double> keyVal = new SimpleEntry<T, Double>(element,score);
elements.add(keyVal);
if (elements.size() > n) {
elements.pollLast();
}
}
/**
* Returns the elements with n smallest scores.
*/
public TreeSet<Entry<T, Double>> get() {
return elements;
}
}
有一个类似的问题,但它不包括流源/内存要求: Find top N elements in an Array