如何使用比较器从向量中找到最小偶数

How to find minimum even number from a vector using comparator

例如:2,3,4,5,6.
预期输出应为 2.

如何为 min_element 函数编写比较器函数以获得最小的偶数。

auto mini_even=*min_element(vec.begin(),vec.end(),cmp);

您可以使用将所有偶数放在奇数之前的比较器,即任何偶数比较小于任何奇数,而所有其他比较照常:

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

int main()
{   
    std::vector<int> vec{1,2,3};
    
    auto cmp = [](int a,int b){
        if (a%2 == b%2) return a < b;
        if (a%2) return false;    // a odd  b even
        return true;              // a even b odd
    };
    auto mini_even=*min_element(vec.begin(),vec.end(),cmp);
    std::cout << mini_even;

}

要处理只包含奇数的向量,您应该检查结果是否为偶数。

如 Jarod42 在评论中所建议的那样,可以通过更优雅的方式定义比较器来实现相同的效果:

const auto projection = [](int n) { return std::make_pair(is_odd(n), n); }; 
const auto comp = [=](int lhs, int rhs){ return projection (lhs) < projection (rhs); };

std::pairs 有一个 operator<,与上面相同,将所有偶数(is_oddfalse 的那些)放在奇数之前.


如果你想在找不到所需元素时按照惯例return vec.end(),你可以将其包装在一个函数中:

template <typename IT>
IT min_even(IT first, IT last) {
    if (first == last) return last;
    auto cmp = .... see above ...
    auto it = min_element(first,last,cmp);
    if (*it % 2) return last;
    return it;
}

可以泛化为任何谓词工作:

template <typename IT, typename Predicate> 
IT min_proj(IT first,IT last,Predicate pred){
    if (first == last) return last;
    const auto projection = [pred](int n) { return std::make_pair(!pred(n), n); }; 
    const auto cmp = [=](int lhs, int rhs){ return projection (lhs) < projection (rhs); };
    auto it = min_element(first,last,cmp);
    if (!pred(*it)) return last;
    return it;
}

Live Demo