从向量中提取最小,最大和中位数的最有效方法是什么

时间:2019-06-05 07:18:29

标签: c++ algorithm median

给定vector<T> vec{...},假设T是数字类型之一,提取其最小值,最大值和中位数的最佳方法是什么?我知道std::nth_elementstd::minmax_element,但是如果一个接一个地调用,它们似乎会做多余的工作。

到目前为止,我想到的最好的主意是只一次叫std :: nth_element 3次。但这仍然需要3N比较,对吗?有什么方法可以重用先前迭代中完成的部分排序吗?

2 个答案:

答案 0 :(得分:11)

使用std::nth_element进行分区,得出中位数,然后在左半部分std::min_element,在右半部分std::max_element进行

如果您需要更快的速度,请根据std::nth_element推出自己的版本。

答案 1 :(得分:3)

另一种选择是为std::nth_element指定自定义比较,以捕获最小值和最大值。最终可能会进行更多的比较和分支,因此这在某些特定的硬件上可能会变慢,这可能取决于您缓存了多少数据等。因此,一如既往,请基准测试一下,但是对于非空的vector a,该技术看起来像这样:

int min = a[0], max = a[0];
std::nth_element(a.begin(), a.begin() + n, a.end(),
    [&](int lhs, int rhs) {
        min = std::min(min, std::min(lhs, rhs));
        max = std::max(max, std::max(lhs, rhs));
        return lhs < rhs;
    });

在我的(〜10yo i5-660)HTPC上使用GCC 7.4并在100到1000之间随机分配100万个int时,nth_element花费的时间少了36% / max比较。