【问题标题】:How to find the median of a large number of integers (they dont fit in memory)如何找到大量整数的中位数(它们不适合内存)
【发布时间】:2013-04-28 22:59:39
【问题描述】:

我知道答案是使用中位数的中位数,但有人能解释一下怎么做吗?

【问题讨论】:

  • 这里有一些关于此的主题:Thread 1Thread 2。还有more
  • 找到适合内存的每个值样本的中值并取其中的中值。
  • 如果你还需要,我找到了快速选择的代码

标签: java median


【解决方案1】:

有线性时间算法可以做到这一点,这个页面可能会有所帮助,http://en.wikipedia.org/wiki/Selection_algorithm,如果您仍然感到困惑,请询问

基本上,选择算法的工作方式类似于快速排序,但每次仅在枢轴一侧进行排序。目标是保持分区,直到您选择的枢轴等于您尝试查找的元素的索引。 这是我为快速选择找到的 java 代码:

public static int selectKth(int[] arr, int k) {
 if (arr == null || arr.length <= k)
  throw new Error();

 int from = 0, to = arr.length - 1;

 // if from == to we reached the kth element
 while (from < to) {
  int r = from, w = to;
  int mid = arr[(r + w) / 2];

  // stop if the reader and writer meets
  while (r < w) {

   if (arr[r] >= mid) { // put the large values at the end
    int tmp = arr[w];
    arr[w] = arr[r];
    arr[r] = tmp;
    w--;
   } else { // the value is smaller than the pivot, skip
    r++;
   }
  }

  // if we stepped up (r++) we need to step one down
  if (arr[r] > mid)
   r--;

  // the r pointer is on the end of the first k elements
  if (k <= r) {
   to = r;
  } else {
   from = r + 1;
  }
 }

 return arr[k];
}

【讨论】:

  • 谢谢,但我的问题是如何使用算法,当所有数字都不适合内存时。谁能详细解释一下
  • 对于这个算法,所有的数字不需要一次在内存中,阅读它
  • 谢谢 - 你能确认我的理解吗?首先,我将把前五个数字带入内存,并使用选择算法找到它们的中位数。我将结果存储在内存中。然后我将接下来的五个数字带入内存 - 并将它们的中位数存储在内存中。等等。即最后我将在内存中有 n/5 个数字。现在我在其中运行一个选择算法来找到这些数字的中位数。
  • 是的,然后你使用选择算法,因为你有一个保证好的枢轴
  • 另一种可能的解决方案是在列表增长时保持中位数(如果这是一个选项)
【解决方案2】:

这里是Median of Medians algorithm. 看看这个

【讨论】:

  • 谢谢,但我的问题是如何使用算法,当所有数字都不适合内存时。谁能详细解释一下
  • 好的,我会在有时间的时候发布描述
【解决方案3】:

查看this question 的前两个答案。如果第一个(频率计数)适用于您的数据/可用存储,那么您可以通过这种方式获得确切的答案。第二种(补救方法)是一种稳健、通用的方法。

【讨论】:

  • 还有一个双堆算法,它使用一个最小堆和一个最大堆并行来找到具有常量存储的中位数,即使是大数字。
  • Thomas,你能提供一个关于这个常量存储两堆算法的参考吗?
  • 谢谢,托马斯。可能是我误解了文章中的设置,但我没有看到那里的存储绑定。看起来堆最终包括所有值。我错过了什么?
猜你喜欢
  • 2020-02-26
  • 2015-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-10
  • 2021-07-10
相关资源
最近更新 更多