按大地图的降序查找前20个值

时间:2013-09-04 18:36:54

标签: java

这是代码

Integer max = Collections.max(map.values());
int count = 20;
while(count>0)
{
    for (Map.Entry<String, Integer> e : map.entrySet())
        if(e.getValue() == max)
        {
            System.out.println(e.getKey() + "occurs" + e.getValue() + "times");
            count--;
        }
        max--;
}

该程序以n平方时间复杂度运行。有没有更好的方法来显示max中具有前20个最大值的条目,按降序排列?

2 个答案:

答案 0 :(得分:3)

一般来说,除非你有证据证明表现不好,否则我会做最简单的事情。所以,作为第一步,我只是对整个地图进行排序,然后迭代前20个元素,如下所示:

Map<?,?> mySortedMap = new TreeMap<?,?>(map);
Iterator<Entry<?,?>> entries = mySortedMap.entrySet().iterator();
for (int i = 0; i<20; i++) {
  System.out.println(entries.next());
}

不要过早优化。现在,如果你有性能问题,那么事情会变得有趣。我将描绘我使用的算法。

  1. 创建一个大小为20的数组
  2. 以任意顺序遍历地图
  3. 如果地图的下一个值位于目前为止看到的前20位,那么请在适当的位置插入数组。
  4. 该算法具有更好的最差和最佳案例运行时间(theta(n))。

答案 1 :(得分:1)

Efficient,O(n log 20),在所有情况下都是正确的,并且不使用JDK之外的任何东西:

PriorityQueue<Map.Entry<String, Integer>> pq = 
  new PriorityQueue<Map.Entry<String, Integer>>(
    20, new Comparator<Map.Entry<String, Integer>() {
      @Override public int compare(
          Map.Entry<String, Integer> e1, Map.Entry<String, Integer> e2) {
        return e2.getValue().compareTo(e1.getValue());
        // not the other way around, since we want the maximum values
      }
    });
for (Map.Entry<String, Integer> entry : map.entrySet()) {
  pq.add(entry);
  if (pq.size() > 20) {
    pq.remove();
  }
}
while (!pq.isEmpty()) {
  Map.Entry<String, Integer> entry = pq.remove();
  System.out.println("Key: " + entry.getKey() + " Value: " + entry.getValue());
}