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

What's the most efficient way to extract min, max & median from a vector

本文关键字:中位数 有效 是什么 方法 最大值 向量 提取 最小值      更新时间:2023-10-16

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

到目前为止,我想出的最好的主意是一次接一个地调用 std::nth_element 3 次。但这仍然需要 3N 比较,对吧?有没有办法重用在以前的迭代中完成的部分排序?

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

如果您需要它比这更快,请根据std::nth_element滚动您自己的版本。

另一种选择是为 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,在 0 到 1000 之间有 100 万个随机intnth_element最小/最大比较比没有大约 36% 的时间长。