在100个数字的数组中找出5个最高数字的总和

时间:2012-04-26 04:18:43

标签: c++ algorithm

数组中有100个数字,我需要找出其中前5个最高数字的平均值。

同样以其中前5个最低数字的平均值。我怎么能去做呢?

4 个答案:

答案 0 :(得分:7)

使用Hoare的选择算法(或中位数的中位数,如果您需要绝对确定计算复杂度),然后添加顶部分区(并除以其大小以获得平均值)。

这比明显的排序方法快一些,而不是分区 - 分区是(O(N)),排序是O(N log(N) )

编辑:在C ++中,对于真正的代码(即除了家庭作业之外的任何事情,其中​​部分要求是完全靠你自己完成任务),你可以使用std::nth_element将输入划分为前5名和所有内容其他

Edit2:这是另一个补充@Nils的快速演示,但这个完整的C ++ 11版本(可以这么说):

#include <numeric>  
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

int main(){
    std::vector<int> x {1, 101, 2, 102, 3, 103, 4, 104, 5, 105, 6};

    auto pos = x.end() - 5;

    std::nth_element(x.begin(), pos, x.end());

    auto sum = std::accumulate(pos, x.end(), 0);
    auto mean = sum / std::distance(pos, x.end());

    std::cout << "sum = " << sum << '\n' << "mean = " << mean << "\n";

    return 0;
}

答案 1 :(得分:1)

杰瑞已经解释了它是如何运作的。我只想在c ++中添加一个实用的代码示例:

#include <algorithm>

int averageTop5 (int list[100])
{
  // move top 5 elements to end of list:
  std::nth_element (list, list+95, list+100);

  // get average (with overflow handling)
  int avg = 0;
  int rem = 0;      
  for (int i=95; i<100; i++)
  {
    avg += list[i]/5;
    rem += list[i]%5;      
  }

  return avg + (rem /5);  
}

使用Jerrys std :: accumulate,这会成为一个双线程,但可能会因整数溢出而失败:

#include <algorithm>
#include <numeric>
int averageTop5 (int list[100])
{
  std::nth_element (list, list+95, list+100);
  return std::accumulate (list+95, list+100, 0)/5;
}

答案 2 :(得分:0)

按升序排序并添加最后五个数字

答案 3 :(得分:0)

将前5个数字复制到数组中。确定该数组中最小元素的位置。对于列表其余部分中的95个数字中的每一个,将其与该最小数字进行比较。如果新号码较大,则将其替换并重新确定短名单中新的最小号码的位置。

最后,将数组求和并除以5.