我寻求显示固定的项目数量在网页上根据它们各自的权重(由一个 Integer).本列表,这些项目是发现可以的几乎任何大小。

第一个解决方案就是要做一个 Collections.sort() 并得到该项目一一个通过 List.是否有一个更优雅的方案,虽然这可能被用来准备,也就是说,顶八个项目?

有帮助吗?

解决方案

只是去Collections.sort(..)。它是足够有效的。

  

此算法提供保证的n log(n)的性能。

您的可以的尝试实施一些更有效的您的具体情况的,如果你知道你的列表中的一些独特的性能,但是这是没有理由的。此外,如果您的列表来自一个数据库,例如,你可以有LIMIT它与订购它,而不是在代码中。

其他提示

你的选择:

  1. 做一个 线性 搜索,保持前N重沿途发现。 这应该快于排序lengthly名单,如果由于某种原因,你不能再使用的排序之间的结果显示网页(例如该清单是在迅速改变).

    更新:我站在正在直线索一定是更好的比排序。看到了维基百科的文章"Selection_algorithm选择k最小的或大的元素"为更好选择的算法。

  2. 手动保持 List (原的一个或一个平行的一)按重量的顺序。你可以使用的方法一样 集合。binarySearch() 确定其中插入每一个新的项目。

  3. 维持 List (原的一个或一个平行的一)按重量以通过调用 集合。sort() 之后每次修改,批修改,或者只是前所显示(可能维持一个修改标志,以避免排序已排列表)。

  4. 使用的数据结构,维持按重量-以为你: 优先排队, 树套, 等等。你也可以创建自己的数据结构。

  5. 手动维持一个第二(可能是重订的)的数据结构的前N项目。这个数据结构是随时更新的原始数据结构的修改。你可以创建自己的数据结构包裹的原始名单和这个"顶级N高速缓冲存储器"在一起。

您可以使用最大堆

如果从数据库中的数据起源,穿上该列的索引,使用ORDER BY和TOP或LIMIT获取只需要显示的记录。

或者一个优先级队列

使用美元

List<Integer> topTen = $(list).sort().slice(10).toList();

不使用美元,应使用sort() Collections.sort()它,然后使用list.sublist(0, n)获得前n项。

由于你说项从中提取这些前N可以是任何尺寸的,等等的列表可以是大I假设,我会增加上述简单sort()答案(其完全适当的合理大小的输入)通过建议的大部分工作这里是找到顶N - 然后分选那些N是微不足道的。是:

Queue<Integer> topN = new PriorityQueue<Integer>(n);
for (Integer item : input) {
  if (topN.size() < n) {
    topN.add(item);        
  } else if (item > topN.peek()) {
    topN.add(item);          
    topN.poll();
  }
}

List<Integer> result = new ArrayList<Integer>(n);
result.addAll(topN);
Collections.sort(result, Collections.reverseOrder());

这里的堆(一个最小堆)至少在尺寸上的限制。有没有真正的需要,使堆了所有项目的。

没有,真的没有。至少不是使用Java的内置方法。

有巧妙的方法来从列表比O(n*log(n))操作更快得到物品的最高(或最低)N号,而是需要你手工编写代码这一解决方案。如果物品撑条相对低(不超过几百),采用Collections.sort()排序,然后抓住前N个数字的数目是去IMO的方式。

取决于有多少。让Ñ定义为键的总数,并且m为要显示的数目。结果 排序整个事情:O(nlogn)结果 在未来数最高每次扫描数组:O(n*m)结果 所以,问题是 - 什么是到m信息n之间的关系? 如果m < log n,扫描效率会更高。结果 否则,m >= log n,这意味着排序会更好。 (因为对于m = log n的边缘情况下,它实际上并没有问题,但排序也会给你的,效益好,排数组,这总是好的。

如果该列表的大小是N,并且要检索的项数是K,需要调用Heapify列表中,其将列表(其必须是可转位的,例如数组)上成优先队列。 (参见在 http://en.wikipedia.org/wiki/Heapsort heapify功能)

在堆上(最大项)的顶部检索的项目需要O(LG N)的时间。所以,你的总时间将是:

O(N + K LG N)

这比O(N LG N)假设ķ更好是小于N小得多。

如果保持有序阵列,或者使用不同的数据结构是不是一种选择,你可以尝试像下面这样。所述O时间类似于排序大阵但在实践中,这应该是更有效的。

small_array = big_array.slice( number_of_items_to_find );
small_array.sort();
least_found_value = small_array.get(0).value;

for ( item in big_array ) {  // needs to skip first few items
  if ( item.value > least_found_value ) {
    small_array.remove(0);
    small_array.insert_sorted(item);
    least_found_value = small_array.get(0).value;
  }
}

small_array可能是一个Object []和内环可与交换,而不是实际删除和插入到一个数组来进行。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top