C++ 标准模板库(STL)中的 <algorithm>
提供了丰富的算法集合,涵盖了排序、查找、修改、比较等常见操作。它们与 C++ 容器紧密结合,能够高效地处理容器中的数据。
1. std::algorithm
的特点
- 通用性:基于迭代器设计,适用于各种容器(如
std::vector
、std::list
)。 - 高效性:大多数算法都经过优化,可以直接用于生产环境。
- 灵活性:许多算法可以通过传递函数对象或 lambda 表达式自定义行为。
2. 常用算法概览
2.1 分类
-
修改容器内容:
- 排序:
std::sort
、std::stable_sort
- 逆序:
std::reverse
- 删除:
std::remove
、std::remove_if
- 替换:
std::replace
、std::replace_if
- 排序:
-
查找元素:
- 普通查找:
std::find
、std::find_if
- 二分查找:
std::binary_search
- 普通查找:
-
数值算法:
- 累加:
std::accumulate
- 部分和:
std::partial_sum
- 累加:
-
比较与检查:
- 全部满足:
std::all_of
- 任意满足:
std::any_of
- 无一满足:
std::none_of
- 全部满足:
3. 算法应用详解
3.1 排序算法
1. std::sort
std::sort
用于对范围内的元素进行快速排序(默认升序)。
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> vec = {5, 2, 9, 1, 5, 6};
// 升序排序
std::sort(vec.begin(), vec.end());
// 自定义排序:降序
std::sort(vec.begin(), vec.end(), [](int a, int b) {
return a > b;
});
for (int val : vec) {
std::cout << val << " ";
}
return 0;
}
2. std::stable_sort
保证排序稳定性(即保持相同元素的原有顺序)。
std::stable_sort(vec.begin(), vec.end());
3. std::reverse
将容器中的元素逆序。
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
std::reverse(vec.begin(), vec.end());
for (int val : vec) {
std::cout << val << " ";
}
return 0;
}
3.2 查找算法
1. std::find
从范围 [first, last)
中找到第一个匹配的元素。
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> vec = {10, 20, 30, 40};
auto it = std::find(vec.begin(), vec.end(), 30);
if (it != vec.end()) {
std::cout << "Found: " << *it << std::endl;
} else {
std::cout << "Not found!" << std::endl;
}
return 0;
}
2. std::find_if
和 std::find_if_not
查找满足特定条件的第一个元素。
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> vec = {10, 25, 30, 40};
auto it = std::find_if(vec.begin(), vec.end(), [](int x) {
return x > 20; // 查找第一个大于 20 的元素
});
if (it != vec.end()) {
std::cout << "Found: " << *it << std::endl;
}
return 0;
}
3. std::binary_search
在有序范围内进行二分查找,返回 true
或 false
。
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> vec = {10, 20, 30, 40, 50};
bool found = std::binary_search(vec.begin(), vec.end(), 30);
std::cout << (found ? "Found" : "Not found") << std::endl;
return 0;
}
3.3 修改算法
1. std::remove
和 std::remove_if
逻辑删除指定的元素(实际未修改容器大小,需要配合 erase
)。
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5, 2, 6};
// 删除所有值为 2 的元素
vec.erase(std::remove(vec.begin(), vec.end(), 2), vec.end());
for (int val : vec) {
std::cout << val << " ";
}
return 0;
}
2. std::replace
和 std::replace_if
将容器中所有匹配的元素替换为新值。
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> vec = {1, 2, 3, 2, 4, 5};
std::replace(vec.begin(), vec.end(), 2, 99); // 把所有 2 替换为 99
for (int val : vec) {
std::cout << val << " ";
}
return 0;
}
3.4 数值算法
1. std::accumulate
对范围内的元素求和或进行累积操作(需要引入 <numeric>
)。
#include <iostream>
#include <vector>
#include <numeric>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
int sum = std::accumulate(vec.begin(), vec.end(), 0);
std::cout << "Sum: " << sum << std::endl;
return 0;
}
2. std::partial_sum
计算部分和。
#include <iostream>
#include <vector>
#include <numeric>
int main() {
std::vector<int> vec = {1, 2, 3, 4};
std::vector<int> result(vec.size());
std::partial_sum(vec.begin(), vec.end(), result.begin());
for (int val : result) {
std::cout << val << " "; // 输出: 1 3 6 10
}
return 0;
}
3.5 条件算法
1. std::all_of
, std::any_of
, std::none_of
检查容器中是否有元素满足条件。
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
bool allPositive = std::all_of(vec.begin(), vec.end(), [](int x) { return x > 0; });
bool hasEven = std::any_of(vec.begin(), vec.end(), [](int x) { return x % 2 == 0; });
bool noNegative = std::none_of(vec.begin(), vec.end(), [](int x) { return x < 0; });
std::cout << "All positive: " << allPositive << std::endl;
std::cout << "Has even: " << hasEven << std::endl;
std::cout << "No negative: " << noNegative << std::endl;
return 0;
}
4. 学习建议与实践
学习重点
- 熟悉算法的通用接口:迭代器范围
[first, last)
。 - 掌握常用算法(如
std::sort
、std::find
、std::accumulate
)。 - 理解如何通过 lambda 表达式自定义算法行为。
练习题
- 使用
std::sort
和std::reverse
对数组进行升序和降序排序。 - 使用
std::find
在容器中查找特定值。 - 使用
std::accumulate
计算数组元素的累积乘积。 - 使用
std::all_of
判断数组是否为正数。
通过以上算法的学习和实践,你将能灵活使用 C++ STL 算法处理复杂的数据操作!