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

发布于 2025-01-16 15:05:34 字数 164 浏览 0 评论 0原文

例如:2,3,4,5,6。
预期输出应该是 2。

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

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

Eg: 2,3,4,5,6.
The expected output should be 2.

How can I write comparator func for min_element func to get the smallest even number.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

反目相谮 2025-01-23 15:05:34

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

#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 autoprojection = [](int n) { return std::make_pair(is_odd(n), n); }; 
const auto comp = [=](int lhs, int rhs){ 返回投影 (lhs) <;投影(右轴); };

std::pair 有一个 operator<,与上面相同,它将放置所有偶数(其中 is_odd>false) 在奇数之前。


如果您想遵循常见做法在找不到所需元素时返回 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;
}

现场演示

You can use a comparator that puts all even numbers before odd ones, ie any even number compares less than any odd, while all other comparisons are as usual:

#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;

}

To handle the case of a vector that only contains odd numbers you should check if the result is even or not.

The same effect can be achieved with a more elegant way of defining the comparator, as suggested by Jarod42 in a comment:

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 have an operator< that will, same as the above, place all even numbers (the ones where is_odd is false) before the odd ones.


And if you want to follow common practice to return vec.end() when the desired element cannot be found, you can wrap it in a function:

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;
}

Which can be generalized to work for any predicate:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文