Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 'std::count_'if'的二进制谓词不起作用_C++_Algorithm_C++11_Lambda_Stdvector - Fatal编程技术网

C++ 'std::count_'if'的二进制谓词不起作用

C++ 'std::count_'if'的二进制谓词不起作用,c++,algorithm,c++11,lambda,stdvector,C++,Algorithm,C++11,Lambda,Stdvector,我目前正在尝试使用lambda函数来std::count_,如果数组中两个连续元素的总和等于一个数字。下面给出了一个示例代码 #include <iostream> #include <vector> #include <algorithm> int main() { const int Number = 3; std::vector<int> vec = {1,1,2,4,5,6}; auto count =

我目前正在尝试使用lambda函数来
std::count_,如果
数组中两个连续元素的总和等于一个数字。下面给出了一个示例代码

#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
    const int Number = 3;
    std::vector<int> vec = {1,1,2,4,5,6};    

    auto count = std::count_if( vec.begin(), vec.end(),
    [&](int A, int B) -> bool
    {   return A+B == Number;   });

    std::cout << count << '\n';
}
问题是它使用一元谓词。编译器告诉你们:“你们给了我一个有两个参数的lambda,我期望lambda有一个参数”


我相信你要找的是。它比较容器的每两个相邻元素(可能使用二进制谓词)。

另一个可能的选项是使用。首先,我要编写一个小助手函数:

#include <numeric>
#include <functional>
#include <iterator>

template <typename ForwardIterator, typename BinaryPredicate>
auto count_pairs_if(ForwardIterator first, ForwardIterator last, 
                    BinaryPredicate pred)
{
    const auto n = std::distance(first, last);
    if (n < 2) return std::size_t {0};
    return std::inner_product(first, std::next(first, n - 1), std::next(first),
                              std::size_t {0}, std::plus<> {}, pred);
}

template <typename Range, typename BinaryPredicate>
auto count_pairs_if(const Range& values, BinaryPredicate pred)
{
    return count_pairs_if(std::cbegin(values), std::cend(values), pred);
}
这里有一个。

如前所述,
std::count\u if
是为一元谓词设计的。因此编译器不能接受lambda,我通过了

过了一会儿,我找到了解决这个问题的另一个办法。如果我提供一个模板函数,它需要

  • 容器的迭代器(即开始和结束)(我需要在其上执行相邻元素检查),以及
  • 二进制谓词,用于检查相邻关系
  • 这可能是一个更自然的解决方案,就像任何其他标准算法一样()


    或者,让谓词记住前面的元素。这是不太推荐的,因为它是一个非通用的解决方案,需要非空的容器()


    std::count\u如果
    需要一个带有单个参数的函数。虽然相邻的\u find只找到第一对,但不计算它们。嗯,对。我不确定
    中是否有任何函数可以使用二进制谓词来计算元素。可能需要外部循环来计数找到的事件。如果您定义了一个自定义迭代器来取消对一对相邻值的引用,则可以使用
    count\u来实现这一点:;2) 您的谓词是更深层次的无载波谓词,即它接受该对。或者甚至可以使用一个有状态谓词来记住以前的值。您可以编写一个模板函数
    nexture\u count
    ,这与
    std::nexture\u find
    非常类似,只需在循环中运行它并返回找到的项的计数。
    #include <numeric>
    #include <functional>
    #include <iterator>
    
    template <typename ForwardIterator, typename BinaryPredicate>
    auto count_pairs_if(ForwardIterator first, ForwardIterator last, 
                        BinaryPredicate pred)
    {
        const auto n = std::distance(first, last);
        if (n < 2) return std::size_t {0};
        return std::inner_product(first, std::next(first, n - 1), std::next(first),
                                  std::size_t {0}, std::plus<> {}, pred);
    }
    
    template <typename Range, typename BinaryPredicate>
    auto count_pairs_if(const Range& values, BinaryPredicate pred)
    {
        return count_pairs_if(std::cbegin(values), std::cend(values), pred);
    }
    
    auto count = count_pairs_if(vec, [=] (auto lhs, auto rhs) { return lhs + rhs == Number; });
    
    template <typename Iterator, typename BinaryPred = std::equal_to<>>
    constexpr std::size_t count_adjacent_if(
       Iterator beginIter,
       const Iterator endIter,
       const BinaryPred pred = {})
    {
       if (beginIter == endIter) return 0; // nothing to do!
       std::size_t count{};
       for (Iterator nextIter{ beginIter }; ++nextIter != endIter; beginIter = nextIter)
          if (pred(*beginIter, *nextIter))
             ++count;
       return count;
    }
    
    const auto count = ::count_adjacent_if(
       vec.cbegin(), vec.cend(), [number](const int lhs, const int rhs) { return lhs + rhs == number; }
    );
    
    int lhs = vec[0];
    const auto count = std::count_if(vec.cbegin() + 1, vec.cend(),
       [&](const int rhs) {
       const bool condition = (lhs + rhs == number); // check for the condition
       lhs = rhs; // change the lhs = rhs (i.e. current element = next element)
       return condition; // return the condition
    });