c++algorithm

Count how many adjacent elements satisfy a predicate


Given a std::vector named v and a predicate p that takes two elements and returns a bool, what is the idiomatic way to count how many adjacent elements in v satisfy p?

The obvious way is to use a loop:

auto count = 0;

for (auto index = 1UZ; index < v.size(); ++index)
{
    if (p(v[index - 1], v[index]))
    {
        ++count;
    }
}

It can look prettier using std::views::pairwise from the ranges library:

for (const auto [left_element, right_element] : std::views::pairwise(v) | std::views::as_const)
{
    if (p(left_element, right_element))
    {
        ++count;
    }
}

But it's the same idea...

I am aware of std::adjacent_find and std::adjacent_difference, but cannot see how to use them for this purpose.

Is there some STL algorithm I can use to accomplish this instead of doing it "manually"?


Solution

  • You can count with std::ranges::count_if:

    #include <algorithm>
    #include <iostream>
    #include <ranges>
    #include <vector>
    
    int main() {
        const auto p = [](const auto& lhs, const auto& rhs) {
            return lhs + rhs == 4;
        };
    
        const std::vector v = {1, 3, 2, 2};
    
        const auto count = std::ranges::count_if(std::views::pairwise(v) | std::views::as_const, [&p](const auto& pair){
            return p(std::get<0>(pair), std::get<1>(pair));
        });
    
        std::cout << count << '\n';
    }