简体   繁体   中英

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.

  • Can a lambda function be used to do this?

  • If so, how do I implement a find_if statement to do what I want?

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.

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

看来您尚未被引入std::upper_bound

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM