如何使用用户定义的谓词查找向量的最大元素

时间:2019-07-18 11:07:54

标签: c++ c++11 stl

我需要找到向量的最大元素。我想使用stl库中的max_element。

我尝试过的代码是:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

class A
{
public:
    A(int _size, long _len) : size(_size), len(_len){}

    int size;
    long len;
};

bool CompareMaxA(const A& _a, const A& _b)
{
    return _a.len > _b.len;
}

int main() {

    vector<A> vec;
    A a1(3,10);
    A a2(5,30);
    vec.push_back(a1);
    vec.push_back(a2);


    auto it = max_element(vec.begin(), vec.end(), CompareMaxA);

    cout << "max = " << it->len ;

    return 0;
}

我得到max = 10,而不是max = 30。 请帮助我了解原因。

3 个答案:

答案 0 :(得分:2)

您的比较功能做错了事。只要true_a.len大,_b.len就会返回std::max_element,但是true需要自定义比较函数,该函数必须在{相反的情况。来自std::max_element上的cppreference:

  

参数

     

[...]

     

comp -比较函数对象(即满足Compare要求的对象),如果第一个参数比第二个参数 小,则返回``true''。

您可以通过以下方式修复它

bool lessThanByLen(const A& _a, const A& _b)
{
    return _a.len < _b.len;
}

auto it = max_element(vec.begin(), vec.end(), lessThanByLen);

由标准库使用/传递给标准库的用于订单关系的自定义比较器始终寻求小于关系。在这种情况下,算法名称(max_element)表示应找到最大值。

请注意,正如@JeJo在评论中指出的那样,您还可以考虑传递lambda:

auto it = max_element(vec.begin(), vec.end(),
    [](const A& lhs, const A& rhs) { return lhs.len < rhs.len; });

答案 1 :(得分:0)

在STL中,期望谓词检查较小的关系(即,如果LHS小于RHS)。如果您的自定义谓词实现了更大的运算符,则结果将相反(例如max-> min)。

解决方案是将>中的CompareMaxA替换为<

答案 2 :(得分:0)

此比较

bool CompareMaxA(const A& _a, const A& _b)
{
    return _a.len > _b.len;
}

如果第一个参数大于第二个参数,则返回true。

标准算法std::max_element使用以下条件

comp( max_value, current_value )

,如果返回值为true,则current_value变为max_value

您的比较函数从不返回true,因为10始终小于30。

如果某个true t小于最初被认为是当前最大值的第一个元素,它将返回current_elemen

因此您的函数将搜索向量中的最小元素。

要查找条件反转的最大元素。

bool CompareMaxA(const A& _a, const A& _b)
{
    return _a.len < _b.len;
}
对应于标准功能对象std::less

考虑以下演示程序

#include <iostream>
#include <functional>
#include <iterator>
#include <algorithm>

/*
//How the algorithm can look

template <class ForwardIterator, class Compare>
ForwardIterator max_element( ForwardIterator first, ForwardIterator last, Compare comp )
{
    auto max_element = first;

    if ( first != last )
    {
        while ( ++first != last )
        {
            if ( comp( *max_element, *first ) ) max_element = first;
        }
    }

    return max_element;
}
*/

int main( void )
{
    int a[] = { 1, 2, 3, 4, 5 };

    auto it = max_element( std::begin( a ), std::end( a ), std::less<>() );

    std::cout << *it << '\n';

    // this corresponds to your comparison function
    it = max_element( std::begin( a ), std::end( a ), std::greater<>() );

    std::cout << *it << '\n';
}

其输出为

5
1

正在使用算法std::max_element和具有类似于标准函数对象std::less的比较函数的最大值。

将算法std::max_element与具有类似于标准功能对象std::greater的比较功能一起使用会得出最小值。

反之亦然

将算法std::min_element与具有类似于标准功能对象std::less的比较功能一起使用会得出最小值。

然后将算法std::min_element与具有类似于标准函数对象std::greater的比较函数一起使用,得出最大值。