user2138149
user2138149

Reputation: 16843

Using std::find_if with std::vector to find smallest element greater than some value

I have a vector of doubles which are ordered.

std::vector<double> vec;
for(double x{0.0}; x < 10.0 + 0.5; x += 1.0) vec.push_back(x);

I am trying to use std::find_if to find the first element, and its corresponding index, of this vector for which y < element. Where y is some value.

For example, if y = 5.5 then the relevant element is element 6.0 which has index 6, and is the 7th element.

I suspect that a lambda function could be used do to this.

Upvotes: 0

Views: 4323

Answers (4)

Slava
Slava

Reputation: 44258

Just use std::upper_bound() - it is more effective (it is using binary search) and does not need a lambda:

auto it = std::upper_bound( vec.begin(), vec.end(), x );

if you need to find lower < x < upper you can use std::equal_range(), but you would need additional logic to find proper lower as std::lower_bound will give element which less or equal to x, so you need to make sure lower is less than x and not equal.

live example

Upvotes: 2

Rakete1111
Rakete1111

Reputation: 48958

Looks like you haven't been introduced to std::upper_bound yet:

std::upper_bound(vec.begin(), vec.end(), x);

Upvotes: 1

max66
max66

Reputation: 66210

If you need the index, you can add a counter.

Something like

x = 5;

cnt = -1;

std::find_if(vec.cbegin(), vec.cend(),
   [&] (double element) { ++cnt; return (x < element); })

Upvotes: -1

user2138149
user2138149

Reputation: 16843

1 line of code is necessary, if a lambda function is used: x is a local double (value we are searching for) const double x = 5.5

std::find_if(vec.cbegin(), vec.cend(), [x] (double element) { return (x < element); })

Breaking this down, we have:

std::find_if(vec.cbegin(), vec.cend(), lambda)

The lambda is:

[x] (double element) { return (x < element); }

This means:

  • capture the local variable x for use inside the lambda body
  • the lambda function takes a single double as an argument (the algorithm find_if will pass each element as it iterates over the vector to this function as element)
  • the function body returns true when the first element is found for which x < element

Note: I answered this question myself while researching possible solutions. The context in which I am using this in my own program is slightly different. In my context, the vector is a specification for numerical boundries, and I am looking to find lower < x < higher. Therefore the code I used is slightly different to this, in that I had to shift my returned iterator by 1 place because of how the numerical boundries are specified. If I introduced a bug in transcribing the solution, let me know.

Upvotes: 3

Related Questions