有"accummulate_if"吗?

JAS*_*SON 19 c++ stl

是否有类似的功能,accummulate()但在执行操作时提供了一致的前提条件来过滤线性容器?我搜索accummulate_if但没有.谢谢!

更新:感谢所有的答案.我最终这样做:

std::for_each(v.begin(), v.end(), [&](int x){if (Pred) sum += x;});

Sam*_*Sam 19

将您自己的二进制op传递给std :: accumulate():

#include <iostream>
#include <vector>
#include <numeric>

bool meets_criteria(int value) {
    return value >= 5;
}

int my_conditional_binary_op(int a, int b) {
    return meets_criteria(b) ? a + b : a;
}

class my_function_object {
private:
    int threshold;
public:
    my_function_object(int threshold) :
            threshold(threshold) {
    }

    bool meets_criteria(int value) const {
        return value >= threshold;
    }

    int operator()(int a, int b) const {
        return meets_criteria(b) ? a + b : a;
    }
};

int main() {
    std::vector<int> v { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    //sum [5...10] = 45
    int sum;

    sum = std::accumulate(v.begin(), v.end(), 0, my_conditional_binary_op);
    std::cout << sum << std::endl;

    //Use a function object to maintain states and additional parameters like 'threshold'
    sum = std::accumulate(v.begin(), v.end(), 0, my_function_object(5));
    std::cout << sum << std::endl;

    return sum;
}
Run Code Online (Sandbox Code Playgroud)


Leo*_*sky 15

你真的必须使用算法吗?像波纹管那样简单的事情不会做什么?

for (const auto& v: V)  if(pred(v)) sum+=v;
Run Code Online (Sandbox Code Playgroud)

山姆的想法也很好.但我会用lambda做到这一点:

 sum = accumulate(
     V.begin(), V.end(), 0, 
     [](int a, int b){return pred(b)? a+b: a;}
 );   
Run Code Online (Sandbox Code Playgroud)

  • 这比接受的50行代码答案更受欢迎 (2认同)
  • 一般来说,使用 std 函数可以使代码更加可靠。例如,请注意,在第一个示例中 sum 未初始化为零。 (2认同)

小智 7

不,但你可以自己写:

template
  <
  typename InputIterator,
  typename AccumulateType,
  typename BinaryOperation,
  typename Predicate
  >
const AccumulateType accumulate_if(
  InputIterator first,
  const InputIterator last,
  AccumulateType init,
  BinaryOperation&& binary_op,
  Predicate&& predicate)
{
  for (; first != last; ++first)
    if (predicate(*first)) init = binary_op(init, *first);
  return init;
}
Run Code Online (Sandbox Code Playgroud)

用法:

int main(int argc, char* argv[])
{
    std::vector<int> v = {1,2,3,4,5};
    std::cout << accumulate_if(v.begin(), v.end(), 0, std::plus<int>(), [] (int n) { return n > 3; });
    return 0;
} // outputs 9
Run Code Online (Sandbox Code Playgroud)