📌 专栏收录:《C++标准库深度实战》第4篇
👉 上一篇:《string 类的那些隐藏技巧,90% 的人不知道!》
🔥 个人主页:EL.King
✨ 人生格言:
“STL不会骗人,循环会。”
—— 用对工具,代码才不“野生”
📖 个人专栏:《C语言》《数据结构》《C++干货分享》《LeetCode刷题》《Linux系统编程》
前言:你的 for 循环,正在拖垮代码效率!
想象这个场景👇:
凌晨2点,你接到告警:服务响应慢了10倍。
你翻遍代码,发现罪魁祸首竟是一段“平平无奇”的循环:
for (int i = 0; i < data.size(); ++i) {
if (data[i].score > 90) {
high_scores.push_back(data[i]);
}
}
而同事用一行
std::copy_if就搞定,速度还快3倍……
别让低效循环,暴露了你的“野生C++程序员”身份!
今天,我就带你解锁 <algorithm> 中 5个高频、高效、面试必问 的算法,让你的代码少写50%、快跑3倍、一眼专业!
💡 记住:在C++里,能用STL算法的地方,就别自己写循环!
一、为什么必须用 <algorithm>?
✅ 三大不可替代优势:
- 性能更强:编译器深度优化,部分算法支持自动并行(如 GCC 的
-fopenmp); - 代码更安全:避免手写越界、迭代器失效等低级错误;
- 意图更清晰:
std::find比for+if更直白地表达“我在找东西”。
📊 实测对比(100万元素 vector):
- 手写 for 查找:12ms
std::find:4ms(快3倍!)
二、5个必会算法(附场景+代码)
1️⃣ std::find / std::find_if —— 查找不再难
#include <algorithm>
#include <vector>
#include <iostream>
int main() {
std::vector<int> nums = {1, 3, 5, 7, 9};
// 找第一个等于5的元素
auto it = std::find(nums.begin(), nums.end(), 5);
if (it != nums.end()) {
std::cout << "Found at index: " << (it - nums.begin()) << "\n"; // 输出: 2
}
// 找第一个大于6的元素(用lambda)
auto it2 = std::find_if(nums.begin(), nums.end(), [](int x) { return x > 6; });
if (it2 != nums.end()) {
std::cout << "First >6: " << *it2 << "\n"; // 输出: 7
}
}
✨ 记忆口诀:
find找值,find_if找条件!
2️⃣ std::sort —— 排序界的王者
std::vector<std::string> names = {"Alice", "Bob", "Charlie"};
// 默认升序
std::sort(names.begin(), names.end());
// 自定义降序(用greater)
std::sort(names.begin(), names.end(), std::greater<>());
// 或用lambda按长度排序
std::sort(names.begin(), names.end(), [](const auto& a, const auto& b) {
return a.size() < b.size();
});
⚠️ 避坑:
sort要求随机访问迭代器(vector/array可以,list不行!)
3️⃣ std::count / std::count_if —— 统计神器
std::vector<int> scores = {85, 92, 78, 96, 88};
// 统计90分以上人数
int top_students = std::count_if(scores.begin(), scores.end(), [](int s) {
return s >= 90;
});
std::cout << "Top students: " << top_students << "\n"; // 输出: 2
4️⃣ std::transform —— 函数式编程入门
std::vector<int> input = {1, 2, 3, 4};
std::vector<int> output(input.size());
// 把每个元素平方
std::transform(input.begin(), input.end(), output.begin(), [](int x) {
return x * x;
});
// output = {1, 4, 9, 16}
💡 比手写 for 更简洁,且天然支持并行(C++17
std::execution::par)
5️⃣ std::remove + erase —— 删除元素的正确姿势
std::vector<int> v = {1, 2, 3, 2, 4};
// 删除所有值为2的元素
v.erase(std::remove(v.begin(), v.end(), 2), v.end());
// v = {1, 3, 4}
❗ 重点:
std::remove不真的删除!它只是把“要保留的元素”移到前面,返回新end。
必须配合erase才能真正缩小容器!👉 这就是著名的 “erase-remove idiom”,面试高频考点!
三、避坑指南:这些错误你肯定犯过!
❌ 错误1:以为 remove 会改变容器大小
→ 它只做“分区”,size() 不变!必须 erase。
❌ 错误2:在 map 上用 std::sort
→ map 本身有序!想自定义顺序?用 std::map<key, value, Compare>。
❌ 错误3:对 list 用 std::sort
→ list 不支持随机访问!要用 list.sort() 成员函数。
四、结尾:从今天起,告别原始循环!
真正的 C++ 高手,不是写得最多的人,而是知道“不用写什么”的人。
这5个算法,覆盖了 80% 的日常开发场景。下次写循环前,请先问自己:
“STL 有没有现成的?”
🌟 行动建议:
- 收藏本文,下次写循环时翻出来对照;
- 尝试替换项目中的一段手写循环为 STL 算法;
- 评论区留言:你最想用哪个算法?或者被哪个坑过?
❤️ 觉得有用?别忘了点赞 + 关注 @EL.King
下一篇预告:《shared_ptr用错=内存泄漏?智能指针避坑全指南》

1245

被折叠的 条评论
为什么被折叠?



