简体   繁体   中英

Counting elements greater than a number in vector

I want to count the number of elements greater than a number in a c++ vector. The threshold value is to be taken input from the user.

The code for counting elements greater than a number is given as:

ctr=count_if(v.begin(),v.end(), greater1);

The corresponding function:

bool greater1(int value)
{
   return value >= 8;
}

The problem is I would know the threshold value(here 8) only before the count_if function call so I need to pass the threshold t as a parameter. How to establish the same?

NB Only for c++11 standard

The easiest way to do this is to use a lambda expression . Using that you can build a functor (called a Closure Object) in the call site of count_if and you can use what you known then inside the body of the lambda. That would leave you with something like

auto minimum_value = /* something that gets the minimum value you want to use for the comparison */
auto count = std::count_if(v.begin(), v.end(),[&](auto const& val){ return val >= minimum_value; });
//                                             ^ use this to capture a reference of minimum_value

Make a function that gives you the threshold function!

auto above(int threshold) {
    // This captures a copy of threshold
    return [=](int value) {
        return value >= threshold;
    };
}; 

You can then get the count using above , just by passing the threshold as an argument:

auto count = count_if(v.begin(), v.end(), above(8)); 

Like NathanOliver said , we need to "capture" the threshold value to be used internally. A lambda accomplishes that, but how?

When you write a lambda like

int threshold = 8;
std::count_if(/*...*/, [threshold](int next_val){return next_val >= threshold;});

In C++11 and beyond, the compiler uses this lambda syntax to generate a lightweight class that exposes the function call operator like so:

struct my_greater_equal
{
   explicit my_greater_equal(int _threshold) : threshold(_threshold){}
   bool operator()(int next_val) const
   {
      return next_val >= threshold;
   }
   int threshold;
};

(This is only mostly like what a lambda looks like)

Then an instance is created and used in count_if as-if:

std::count_if(my_collection.cbegin(), my_collection.cend(), my_greater_equal{8});

Internally, std::count_if calls my_greater_equal::operator() for each element in your collection.

Pre-C++11 we had to manually create these lightweight function objects (sometimes called functors even if that's not technically correct)

C++03 Demo

Things are much easier now :-)

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