C++ 算法与 ranges:用 find_if、transform 写清数据处理意图

C++ 算法与 ranges:用 find_if、transform 写清数据处理意图

很多循环并不复杂,只是在寻找一个元素,或者把每个元素转换成另一种值。把这种意图交给标准算法,代码通常比手动维护下标更容易检查。

最低标准:C++20。本篇同时展示传统迭代器算法与 ranges 算法。

1. 查找符合条件的元素,再生成结果

cpp 复制代码
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>

struct Item { std::string name; int price; };

int main() {
    std::vector<Item> items{{"pen", 3}, {"book", 12}, {"bag", 35}};
    auto found = std::find_if(items.begin(), items.end(),
                              [](const Item& x) { return x.price >= 10; });
    if (found != items.end()) std::cout << found->name << '\n';

    std::vector<int> doubled;
    std::ranges::transform(items, std::back_inserter(doubled),
                           [](const Item& x) { return x.price * 2; });
    for (int value : doubled) std::cout << value << ' ';
    std::cout << '\n';

    auto cheap = std::ranges::find_if(items,
        [](int price) { return price < 5; }, &Item::price);
    if (cheap != items.end()) std::cout << cheap->name << '\n';
}

输出依次为 book、6 24 70、pen。find_if 返回第一个满足条件的位置;找不到时返回结束迭代器,必须先判断再解引用。它不会把所有匹配项收集起来。

2. ranges 的投影让条件更专注

最后一次查找把 &Item::price 作为投影:算法先取得价格,再把价格交给条件函数。这样条件本身无需知道 Item 的其他字段。

ranges 版本通常可以直接接收容器,不必重复写 begin/end。不过"写法更短"不意味着生命周期问题消失。不要长期保存容器失效后的迭代器;对某些临时范围调用算法时,返回类型会使用 dangling 来阻止错误借用。

3. transform 不会自动扩大普通目标容器

若把空 vector 的 begin 作为输出位置,算法不会自动插入元素。应先 resize 到足够长度,或像示例一样使用 back_inserter。reserve 只预留容量,不会增加 size,不能替代 resize。

输入和输出的关系也要遵守算法约定:需要原地转换时,可以把输出起点设为输入起点;不要随意使用错位重叠区间。转换过程中也不应通过副作用改变正在遍历的容器结构。

4. 算法表达意图,普通循环表达流程

"找第一个""逐个转换""判断是否全部满足"很适合算法;如果每一步都有复杂状态迁移、多个退出条件和错误恢复,清晰的普通循环可能更合适。

把判断函数写成无意外副作用的小函数,避免假设 transform 的调用顺序可以承担业务流程。最终目标不是消灭 for,而是让读者一眼看出代码在做什么。

进一步阅读:Microsoft 标准算法参考。

相关推荐
红姐跨境书1 小时前
AI 的底层逻辑:从数据、算法到智能的本质
人工智能·算法
张小姐的猫1 小时前
【AI大模型接入SDK】 —— 前端页面 & 项目总结与拓展
前端·数据结构·数据库·c++·人工智能·chatgpt
青山是哪个青山1 小时前
LeetCode 64:最小路径和
算法
blxr_1 小时前
力扣hot100寻找重复数https://leetcode.cn/problems/find-the-duplicate-number/
算法·leetcode·职场和发展
政企项目老覃1 小时前
金融医疗数据脱敏与隐私计算:从字段打码到联邦建模的落地复盘
程序人生·算法·金融·数据分析
霸道流氓气质1 小时前
Mermaid 图表完全指南:从文本语法到LangGraph4j工作流可视化实战
开发语言·python
❀͜͡傀儡师1 小时前
Spring Boot 实现图片盲水印:基于 DCT 频域算法的隐形数字水印
spring boot·算法
泡海椒2 小时前
JQuick-Excel 项目定位与适用场景:声明式 Java Excel 的边界
java·开发语言·excel
AC赳赳老秦2 小时前
财报附注表格精准提取:OpenClaw 从 PDF 年报附注挖掘隐藏明细,补齐财务分析维度
java·汇编·c++·python·青少年编程·deepseek·openclaw