在 vector<double> 上使用 std::max_element

Posted

技术标签:

【中文标题】在 vector<double> 上使用 std::max_element【英文标题】:Using std::max_element on a vector<double> 【发布时间】:2012-04-26 21:01:03 【问题描述】:

我正在尝试使用 std::min_elementstd::max_element 返回双精度向量中的最小和最大元素。我的编译器不喜欢我目前尝试使用它们的方式,而且我不理解错误消息。我当然可以编写自己的程序来找到最小值和最大值,但我想了解如何使用这些函数。

#include <vector>
#include <algorithm>

using namespace std;

int main(int argc, char** argv) 

    double cLower, cUpper;
    vector<double> C;

    // Code to insert values in C is not shown here

    cLower = min_element(C.begin(), C.end());
    cUpper = max_element(C.begin(), C.end());

    return 0;

这是编译器错误:

../MIXD.cpp:84: error: cannot convert '__gnu_cxx::__normal_iterator<double*, std::vector<double, std::allocator<double> > >' to 'double' in assignment
../MIXD.cpp:85: error: cannot convert '__gnu_cxx::__normal_iterator<double*, std::vector<double, std::allocator<double> > >' to 'double' in assignment

我做错了什么?

【问题讨论】:

请注意,如果您使用的是 C++11,则可以使用 std::minmax_element @GManNickG:我不知道那个函数。由于行为不同,我在答案中添加了一条注释以将其合并。 【参考方案1】:

min_elementmax_element 返回迭代器,而不是值。所以你需要*min_element...*max_element...

【讨论】:

迭代器是一个指针,它指向事物。但它可能是也可能不是普通的指针。例如,如果迭代器引用列表中的一个对象,则递增它使其指向列表中的下一个对象。增加一个普通指针只对像向量这样的集合起作用,这些集合保证将它们的内容存储在序列内存地址中。 如果向量为空*max_element 会引发错误。有没有办法处理这个问题?现在我检查向量是否为空,然后使用*max_element 我认为这是最好的解决方案。无论如何,您需要特别处理这种情况,因为没有可以返回的合理值。 @Moj:你可以对照C.end()检查迭代器。【参考方案2】:

正如其他人所说,std::max_element()std::min_element() 返回iterators,需要取消引用以获得

返回迭代器(而不仅仅是值)的优点是它允许您确定容器中具有最大(或最小)值的(第一个)元素的位置

例如(为简洁起见,使用 C++11):

#include <vector>
#include <algorithm>
#include <iostream>

int main()

    std::vector<double> v 1.0, 2.0, 3.0, 4.0, 5.0, 1.0, 2.0, 3.0, 4.0, 5.0;

    auto biggest = std::max_element(std::begin(v), std::end(v));
    std::cout << "Max element is " << *biggest
        << " at position " << std::distance(std::begin(v), biggest) << std::endl;

    auto smallest = std::min_element(std::begin(v), std::end(v));
    std::cout << "min element is " << *smallest
        << " at position " << std::distance(std::begin(v), smallest) << std::endl;

这会产生:

Max element is 5 at position 4
min element is 1 at position 0

注意:

使用上面 cmets 中建议的 std::minmax_element() 对于大型数据集可能会更快,但可能会给出稍微不同的结果。我上面示例的 values 将是相同的,但“max”元素的位置将是 9,因为...

如果多个元素等价于最大元素,则返回最后一个此类元素的迭代器。

【讨论】:

@synaptik:这也适用于其他容器类型 :)【参考方案3】:

min/max_element 将 iterator 返回到 min/max 元素,而不是 min/max 元素的值。您必须取消引用迭代器才能获取值并将其分配给双精度值。那就是:

cLower = *min_element(C.begin(), C.end());

【讨论】:

以上是关于在 vector<double> 上使用 std::max_element的主要内容,如果未能解决你的问题,请参考以下文章

是否可以基于 Vector<double> 在 .Net 中创建高效的 SIMD 双精度 Vector3

如何将文件读取为vector<vector<double>>?

如何将 std::vector<std::vector<double>> 转换为 torch::Tensor?

vector<double>::size_type 与 double

带有 std::function<double(std::vector<double>) 回调的 cppyy

排序和删除向量中的重复项<vectors< double>>