【问题标题】:Counting elements greater than a number in vector计算大于向量中数字的元素
【发布时间】:2019-07-22 18:41:16
【问题描述】:

我想计算大于 c++ 向量中数字的元素数。阈值取自用户输入。

计算大于数字的元素的代码如下:

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

对应函数:

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

问题是我只会在 count_if 函数调用之前知道阈值(这里是 8),所以我需要将阈值 t 作为参数传递。如何建立相同的?

【问题讨论】:

    标签: c++ vector stdvector counting c++03


    【解决方案1】:

    注意仅适用于 c++11 标准

    最简单的方法是使用lambda expression。使用它,您可以在count_if 的调用站点中构建一个函子(称为闭包对象),然后您可以在 lambda 的主体中使用您所知道的内容。那会给你留下类似的东西

    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
    

    【讨论】:

    • 无论是按值还是按引用捕获 lambda 对基本整数类型来说并不重要。通常你应该按价值捕获
    • 当我尝试运行代码时,auto minimum_value = k+1 行中出现错误 [Error] C:\Users\User\Documents\cp\Untitled2.cpp:37: error: ISO C++ forbids declaration of minimum_value' with no type`。不知道为什么?可能是因为C++版本不兼容或者编译器不兼容?
    【解决方案2】:

    制作一个给你阈值函数的函数!

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

    然后您可以使用above 获取计数,只需将阈值作为参数传递:

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

    【讨论】:

      【解决方案3】:

      NathanOliver said 一样,我们需要“捕获”要在内部使用的阈值。一个 lambda 实现了这一点,但是如何实现呢?

      当你写一个类似的 lambda 时

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

      在 C++11 及更高版本中,编译器使用此 lambda 语法生成一个轻量级的类,该类公开函数调用运算符,如下所示:

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

      (这只是 大部分类似于 lambda 的样子)

      然后在count_if as-if: 中创建并使用一个实例:

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

      在内部,std::count_if 为您集合中的每个元素调用 my_greater_equal::operator()

      在 C++11 之前,我们必须手动创建这些轻量级函数对象(有时称为 函子,即使这在技术上不正确)

      C++03 Demo

      现在事情容易多了:-)

      【讨论】:

      • 我尝试了代码,但在std::count_if(v1.begin(),v1.end(), [threshold](int next_val){return next_val >= threshold;}); 行中出现[Error] C:\Users\User\Documents\cp\Untitled2.cpp:33: error: expected primary-expression before '[' token 错误我不明白他们想说什么?
      • @Excelsior:您使用的是什么编译器,它使用的是什么标准的 C++?
      • g++编译器和c++版本
      • @Excelsior:如果版本低于 C++11,则不能使用 lambda。您必须使用我上面概述的函数对象方法。
      • 是的,你是对的,而不是 lambda 我使用了你的函数对象方法,我在 std::count_if(v1.begin(), v1.end(), my_greater_equal{k+1}); 行中得到了错误 [Error] C:\Users\User\Documents\cp\Untitled2.cpp:44: error: expected primary-expression before '{' token 。我在发布这个问题之前写了几乎相同的代码并得到了同样的错误。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-02-27
      • 1970-01-01
      • 2020-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多