【发布时间】:2017-07-05 14:06:48
【问题描述】:
我想知道是否有一个标准函数可以返回给定范围元素的返回值的最小值/最大值。像这样的:
std::vector<int> list = { -2, -1, 6, 8, 10 };
auto it =
std::find_min_return_value(list.begin(), list.end(), std::abs, std::less<int>);
// it should be the iterator for -1
如果没有这样的问题,解决此类问题的最佳方法是什么? 我的列表很长,我真的不想复制它,也不想调用每个元素多次查找最小返回值的函数。谢谢!
更新:
根据 ForEveR 使用 std::min_element 的建议,我做了以下基准测试:
std::vector<double> list = { -2, -1, 6, 8, 10 };
auto semi_expensive_test_function = [] (const double& a) { return asin(sin(a)); };
for(int i = 0; i < 10000000; ++i)
{
auto it = std::min_element(list.begin(), list.end(),
[&] (const double& a, const double& b) mutable
{
return(semi_expensive_test_function(a) < semi_expensive_test_function(b));
});
}
效果很好:
./a.out 11.52s user 0.00s system 99% cpu 11.521 total
修改代码以改用有状态 lambda 后:
for(int i = 0; i < 10000000; ++i)
{
auto it = std::min_element(list.begin() + 1, list.end(),
[&, current_min_value = semi_expensive_test_function(*(list.begin()))] (const double& a, const double& b) mutable
{
double current_value = semi_expensive_test_function(b);
if(current_value < current_min_value)
{
current_min_value = std::move(current_value);
return true;
}
return false;
});
}
结果:
./a.out 6.34s user 0.00s system 99% cpu 6.337 total
使用有状态的 lambda 似乎是要走的路。问题是:有没有更代码紧凑的方式来实现这一点?
【问题讨论】:
-
取决于,如果没有时间复杂度约束,可以 std::sort(list.begin(), list.end()) 第一个元素是最小值,最大值是最后一个使用默认值比较器,即 nlogn。
-
std::min_element?std::minmax_element? -
或者
std::minmax_element如果你需要两者 -
@AdamHunyadi
std::minmax_element(list.begin(), list.end(), [] (int a, int b) { return std::abs(a) < std::abs(b); }) -
@XinHuang 列表很长,不想复制。另外,我想为每个元素调用一次我查找其最小返回值的函数。