Is there a way to find the minimum odd element of a vector of integers without basically reimplementing std::min_element and without doing additional work like computing the vector of odd integers first?
- I honestly don't know why you got downvoted. Sure it's a quite trivial problem and could have a better title, but that asks for edit, not downvotes.Guillaume Racicot– Guillaume Racicot2021-01-19 20:20:49 +00:00Commented Jan 19, 2021 at 20:20
- If you can, add a simple example with a comment that points where you would expect to put your condition.Guillaume Racicot– Guillaume Racicot2021-01-19 20:23:30 +00:00Commented Jan 19, 2021 at 20:23
4 Answers
While a custom comparison object suggested in another answer will be a simple solution for std::min_element (and similar) in particular, it won't work with all standard algorithms. A general approach that works with any standard algorithm is to define a custom iterator.
Customising, combining and extending standard algorithms can nearly always be achieved with iterators. Writing custom iterators from scratch involves a lot of boilerplate and unfortunately standard doesn't provide templates for many iterator adaptors. Boost does provide plenty of iterator adaptor templates, and in this case boost::filter_iterator should prove useful.
Instead of the more traditional iterator algorithms, you could use range algorithms instead.
Since C++20, there are a host of standard range adaptors for range algorithms which are easy to compose:
auto it = std::ranges::min_element( container | std::views::filter(condition) ); Note that at the moment of writing, only libstdc++ has implemented the ranges standard library.
1 Comment
A simple solution consists in using a custom comparator function with std::min_element.
What should be added in the following code is to check that the obtained value is odd indeed, as mentioned by @MSalters in their answer and by @Kevin in a comment.
#include <iostream> #include <algorithm> #include <vector> int main() { std::vector<int> v = {0, 3, 4, 1}; auto comp = [](int a, int b) { if ((a%2) and (b%2 == 0)) return true; if ((a%2 == 0) and (b%2)) return false; return a < b; }; auto min_odd = std::min_element(v.begin(), v.end(), comp); std::cout << *min_odd << std::endl; } Yes, that's not very hard. Implement a custom comparison that sorts each even element above all odd elements. You still need to sort the odd elements in their usual order, and at the end check that there was at least one odd element in the vector.
4 Comments
sd::min_element ?