You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用STL算法统计std::vector中满足指定谓词的相邻元素对数

如何使用STL算法统计std::vector中满足指定谓词的相邻元素对数

嘿,这个问题问到点子上了!你已经想到了手动循环和C++20里的std::views::pairwise,其实确实有更贴合STL风格的“非手动”做法,不用自己写累加逻辑,完全用STL算法搞定~

一、C++20及以上:用Ranges库一步到位

C++20引入的Ranges库把这种场景的处理变得特别优雅,直接结合std::views::pairwise和std::ranges::count_if就行,一行核心代码解决问题:

#include <vector>
#include <ranges>
#include <algorithm>

// 示例谓词:判断前一个元素小于后一个
bool is_less(int a, int b) {
    return a < b;
}

int main() {
    std::vector<int> v = {1, 3, 2, 4, 5, 5};
    
    // 统计满足is_less的相邻元素对数量
    auto count = std::ranges::count_if(
        std::views::pairwise(v),
        [&](const auto& elem_pair) {
            return is_less(elem_pair.first, elem_pair.second);
        }
    );
    // 这里count的结果是3:(1,3)、(2,4)、(4,5)
}

原理很简单:std::views::pairwise会把原容器的相邻元素打包成一个个元素对(比如std::pair<const T&, const T&>),然后std::ranges::count_if会遍历这些元素对,自动统计满足谓词的数量——完全不用自己写循环累加,纯STL算法组合,这就是最地道的写法。

二、C++20之前:用std::accumulate实现

如果还在用C++17或更早的版本,没有Ranges库,那std::accumulate是个好选择,它可以帮我们同时跟踪计数和前一个元素,不用额外的临时容器:

#include <vector>
#include <numeric>

bool is_less(int a, int b) {
    return a < b;
}

int main() {
    std::vector<int> v = {1, 3, 2, 4, 5, 5};
    if (v.size() < 2) {
        // 容器元素不足2个,没有相邻元素对
        return 0;
    }

    // 用accumulate同时跟踪计数和前一个元素
    auto result = std::accumulate(
        std::next(v.begin()), v.end(),
        std::make_pair(0, v.front()), // 初始值:计数0,前一个元素是容器第一个元素
        [&](std::pair<int, int> acc, const auto& curr) {
            if (is_less(acc.second, curr)) {
                // 满足谓词,计数+1,更新前一个元素为当前元素
                return std::make_pair(acc.first + 1, curr);
            } else {
                // 不满足,计数不变,更新前一个元素
                return std::make_pair(acc.first, curr);
            }
        }
    );

    auto count = result.first; // 最终统计结果
}

这里std::accumulate不再是单纯做数值累加,而是用一个pair来保存累加的状态:第一个成员是当前统计的数量,第二个成员是上一个遍历到的元素。遍历从第二个元素开始,每次和前一个元素比较,更新状态即可。

三、关于你提到的std::adjacent_find和std::adjacent_difference

你说的这两个算法确实不太适合直接统计数量:

  • std::adjacent_find只能找到第一个满足条件的相邻元素对,没法批量统计所有符合的情况;
  • std::adjacent_difference虽然可以处理相邻元素,但它的核心是计算差值(或自定义二元操作的结果),如果硬要用它,得先把满足谓词的情况转换成1,不满足的转换成0,再用std::accumulate累加这些值,但这样需要额外的临时容器存储中间结果,不如前面两种方法高效简洁,所以一般不推荐这么用。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 11:59:33