Simplicity
Simplicity

Reputation: 48916

Selecting the maximum “n” values

If I have the following:

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

    struct Features{ int F1, F2, F3, F4; };

    int criterionFunction(Features const& features) {
        return
            -2*features.F1*features.F2
            +3*features.F1
            +5*features.F2
            -2*features.F1*features.F2*features.F3
            +7*features.F3
            +4*features.F4
            -2*features.F1*features.F2*features.F3*features.F4; }

How can I apply transform() to find the first THREE max values?

Thanks.

Upvotes: 1

Views: 180

Answers (3)

Philipp
Philipp

Reputation: 49802

Here is an example using nth_element with a simpler feature object and criterion function (to reduce clutter):

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

typedef int Features;

int criterionFunction(Features features) {
  return features;
}

int main() {
  std::vector<Features> v { 0, 4, 2, 5, 4, 3, -2, 1 };
  std::nth_element(v.begin(), v.begin() + 3, v.end(),
                   [](Features a, Features b) {
                       return criterionFunction(a) > criterionFunction(b);
                   });
  std::copy(v.begin(), v.begin() + 3,
            std::ostream_iterator<Features>(std::cout, " "));
}

For your original Features object, it might be useful to cache/memoize the results of the criterionFunction to prevent duplicate calls.

Note that nth_element does not sort the elements in the two partitions; if you want the first three elements in sorted order, use partial_sort instead.

Upvotes: 2

Benjamin Lindley
Benjamin Lindley

Reputation: 103693

With a combination of std::transform, std::multiset, and an insert iterator you could.

vector<Features> v;
...fill it up
multiset<int> ms;
transform(v.begin(), v.end(), inserter(ms, ms.begin()), criterionFunction);

Then the three max values are the last three elements.

Upvotes: 1

Stack Overflow is garbage
Stack Overflow is garbage

Reputation: 247919

You can't. It's not what std::transform does.

transform applies a single function to every element in the sequence. It does not select specific elements.

Upvotes: 1

Related Questions