Home > front end >  How to find minimum even number from a vector using comparator
How to find minimum even number from a vector using comparator

Time:03-25

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

CodePudding user response:

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

  • Related