【C++】【STL算法】那些STL算法替代的循环

有一句谚语说:"如果你显式使用循环的话,说明你不了解STL算法。"STL算法有很多自己典型使用场景:数据处理和转换,搜索和过滤,排序与分组,数学计算,集合操作等。下面示例如何将代码中的循环,用STL算法替代,主要有std::for_each()/std::find()/std::find_if()/std::count_if()/std::any_of()/std::all_of()/std::none_of()/std::transform()/std::copy_if()/std::remove_if()/std::accumulate()/std::sort()/std::unique()/std::replace_if()。

1. 遍历并执行操作

cpp 复制代码
//目标:对容器中每个元素执行某个动作

//传统循环
for (int x : v) { std::cout << x << " "; }

//STL 算法
std::for_each(v.begin(), v.end(), [](int x) { std::cout << x << " "; });

//说明
//std::for_each 明确表达"对每个元素执行操作"的语义
//更容易被并行化(std::for_each(std::execution::par, ...))

2. 查找元素

cpp 复制代码
//目标:判断容器中是否存在某个值

//传统循环

bool found = false; for (int x : v) { if (x == 10) { found = true; break; } }

//STL 算法

auto it = std::find(v.begin(), v.end(), 10); bool found = (it != v.end());

3. 条件查找(第一个满足条件的元素)

cpp 复制代码
//传统循环

int result = -1; for (int x : v) { if (x > 10) { result = x; break; } }

//STL 算法

auto it = std::find_if(v.begin(), v.end(), [](int x) { return x > 10; });

4. 统计数量

cpp 复制代码
//目标:统计满足条件的元素个数

//传统循环

int count = 0; for (int x : v) { if (x % 2 == 0) { ++count; } }

//STL 算法

int count = std::count_if(v.begin(), v.end(), [](int x) { return x % 2 == 0; });

5. 判断"是否存在 / 是否全部满足"

cpp 复制代码
//是否存在

bool has_negative = std::any_of(v.begin(), v.end(), [](int x) { return x < 0; });

//是否全部满足

bool all_positive = std::all_of(v.begin(), v.end(), [](int x) { return x > 0; });

//是否全部不满足

bool none_zero = std::none_of(v.begin(), v.end(), [](int x) { return x == 0; });

6. 修改元素(就地变换)

cpp 复制代码
//目标:对每个元素进行变换

//传统循环

for (int& x : v) { x *= 2; }

//STL 算法

std::transform(v.begin(), v.end(), v.begin(), [](int x) { return x * 2; });

7. 拷贝 + 条件过滤

cpp 复制代码
//目标:筛选元素到新容器

//传统循环
std::vector<int> result; for (int x : v) { if (x > 0) { result.push_back(x); } }

//STL 算法
std::vector<int> result; std::copy_if(v.begin(), v.end(), std::back_inserter(result), [](int x) { return x > 0; });

8. 删除元素(erase-remove 惯用法)

cpp 复制代码
//目标:从容器中删除满足条件的元素

//传统循环(容易出错)

for (auto it = v.begin(); it != v.end(); ) { if (*it < 0) it = v.erase(it); else ++it; }

//STL 算法

v.erase(std::remove_if(v.begin(), v.end(), [](int x) { return x < 0; }), v.end());

9. 累加 / 聚合

cpp 复制代码
//目标:求和或聚合计算

//传统循环

int sum = 0; for (int x : v) { sum += x; }

//STL 算法

int sum = std::accumulate(v.begin(), v.end(), 0);

//自定义聚合

int product = std::accumulate(v.begin(), v.end(), 1, std::multiplies<>());

10. 排序 + 自定义规则

cpp 复制代码
//传统循环
//实际上很少手写排序循环(复杂且易错)

//STL 算法
std::sort(v.begin(), v.end(), [](int a, int b) { return a > b; });

11. 相邻元素处理

cpp 复制代码
//目标:消除连续重复值
//STL 算法
v.erase(std::unique(v.begin(), v.end()), v.end());

12. 条件替换

cpp 复制代码
//传统循环
for (int& x : v) { if (x < 0) x = 0; }
//STL 算法
std::replace_if(v.begin(), v.end(), [](int x) { return x < 0; }, 0);
相关推荐
Jasmine_llq17 分钟前
《P3157 [CQOI2011] 动态逆序对》
算法·cdq 分治·动态问题静态化+双向偏序统计·树状数组(高效统计元素大小关系·排序算法(预处理偏序和时间戳)·前缀和(合并单个贡献为总逆序对·动态问题静态化
学嵌入式的小杨同学23 分钟前
【Linux 封神之路】信号编程全解析:从信号基础到 MP3 播放器实战(含核心 API 与避坑指南)
java·linux·c语言·开发语言·vscode·vim·ux
Re.不晚1 小时前
Java入门17——异常
java·开发语言
爱吃rabbit的mq1 小时前
第09章:随机森林:集成学习的威力
算法·随机森林·集成学习
精彩极了吧1 小时前
C语言基本语法-自定义类型:结构体&联合体&枚举
c语言·开发语言·枚举·结构体·内存对齐·位段·联合
(❁´◡`❁)Jimmy(❁´◡`❁)2 小时前
Exgcd 学习笔记
笔记·学习·算法
YYuCChi2 小时前
代码随想录算法训练营第三十七天 | 52.携带研究材料(卡码网)、518.零钱兑换||、377.组合总和IV、57.爬楼梯(卡码网)
算法·动态规划
南极星10052 小时前
蓝桥杯JAVA--启蒙之路(十)class版本 模块
java·开发语言
baidu_247438612 小时前
Android ViewModel定时任务
android·开发语言·javascript
CSDN_RTKLIB2 小时前
【四个场景测试】源文件编码UTF-8 BOM
c++