我尝试计算名为median
的矢量的中位数:
std::nth_element(median.begin(), median.begin() + median.size() / 2, median.end());
medianVal = median[median.size() / 2];
cout << "The median is " << medianVal << endl;
这很好用。但我需要在其原始向量中获得中值的位置。我怎么能这么快地做到这一点?
答案 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风格的数组,我认为它甚至适用于哨兵。
答案 1 :(得分:2)
根据文档(http://en.cppreference.com/w/cpp/algorithm/nth_element),您正在使用的函数实际上会对数组进行重新排序。
您需要保留原件的副本并逐步执行,以找到与中位数匹配的元素。
另一种完成它的方法是使用元组向量,其中索引只是作为元组的第二个成员存储。如果当然你还在某个时候踩过矢量。
答案 2 :(得分:1)