C ++用参考计算中位数

时间:2016-02-10 19:53:37

标签: c++ median

我尝试计算名为median的矢量的中位数:

std::nth_element(median.begin(), median.begin() + median.size() / 2, median.end());     
medianVal = median[median.size() / 2];  
cout << "The median is " << medianVal << endl;

这很好用。但我需要在其原始向量中获得中值的位置。我怎么能这么快地做到这一点?

3 个答案:

答案 0 :(得分:4)

我假设你不想重新订购原始容器。如果错了,有更简单的方法。

nth_element需要一个比较器。

首先在原始容器中创建一个迭代器向量,然后编写一个带有2个迭代器的比较器,对它们进行推理,然后比较结果。

template<class C>
auto median(C const& c){
  using std::begin; using std::end;
  auto start = begin(c);
  auto finish = end(c);
  using iterator = decltype(start);
  std::vector<iterator> working;
  for(auto it = start; it != finish; ++it)
    working.push_back(it);
  if (working.empty())
      return start;
  std::nth_element(
      begin(working), begin(working) + working.size() / 2, end(working),
      [](iterator lhs, iterator rhs){
          return *lhs < *rhs;
      }
  );
  return *(begin(working) + working.size() / 2);
}

这确实依赖于一些C ++ 14(自动返回类型推导),但是每个主要的编译器(可能除了icc?)现在都支持它。

它足够灵活,甚至可以处理C风格的数组,我认为它甚至适用于哨兵。

Demo

答案 1 :(得分:2)

根据文档(http://en.cppreference.com/w/cpp/algorithm/nth_element),您正在使用的函数实际上会对数组进行重新排序。

您需要保留原件的副本并逐步执行,以找到与中位数匹配的元素。

另一种完成它的方法是使用元组向量,其中索引只是作为元组的第二个成员存储。如果当然你还在某个时候踩过矢量。

答案 2 :(得分:1)

在不知道问题的确切性质或涉及的数据系列中的元素数量的情况下,很难知道“快速执行此操作”是什么意思,但是您可能希望查看“堆中位数”又名“滚动中位数”又称“流中位数”算法描述了SO站点中的herehereherehere

使用此方法,您可以存储当前候选中值的索引,而无需再次迭代原始数据数组以查找中值的索引。您无需修改​​原始容器的顺序。