STL(标准模板库)里的 <algorithm>
是 C++ 中非常强大的一部分,它提供了大量的通用算法函数,可以对容器(如 vector
, list
, deque
等)进行排序、查找、修改、遍历等操作。
STL <algorithm>
学习路径
目录
1. 遍历与修改类算法(基础)
算法 | 作用 |
---|---|
for_each | 遍历容器,对每个元素执行指定操作(如打印、修改值,无返回值) |
transform | 将容器元素按规则转换后,存储到目标容器(如数值加倍、大小写转换) |
for_each代码示例
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v = {1, 2, 3, 4};
std::vector<int> result(v.size());
std::transform(v.begin(), v.end(), result.begin(), [](int x) {
return x * 2;
});
for (int x : result)
std::cout << x << " "; // 输出:2 4 6 8
return 0;
}
std::transform
会自己使用 v.begin()
到 v.end()
范围内的值(依次取出 1, 2, 3, 4
),传递给 [](int x)
这个 lambda 处理。
2. 查找类算法 谓词(即条件函数)
算法 | 作用 |
---|---|
find | 查找容器中第一个等于指定值的元素,返回迭代器 |
find_if | 查找容器中第一个满足谓词条件()的元素,返回迭代器 |
count | 统计容器中等于指定值的元素数量 |
count_if | 统计容器中满足谓词条件的元素数量 |
all_of | 检查是否所有元素都满足谓词条件(返回 true /false ) |
any_of | 检查是否至少有一个元素满足谓词条件 |
none_of | 检查是否没有元素满足谓词条件 |
#include <iostream>
#include <vector>
#include <algorithm> // 包含所有算法
int main() {
std::vector<int> v = {1, 2, 3, 4, 2, 5};
// find:查找第一个等于2的元素
auto it_find = std::find(v.begin(), v.end(), 2);
if (it_find != v.end())
std::cout << "find: 找到了 " << *it_find << ",位置是 " << std::distance(v.begin(), it_find) << "\n";
else
std::cout << "find: 没找到\n";
// find_if:查找第一个大于3的元素
auto it_find_if = std::find_if(v.begin(), v.end(), [](int x) { return x > 3; });
if (it_find_if != v.end())
std::cout << "find_if: 找到了大于3的元素 " << *it_find_if << "\n";
else
std::cout << "find_if: 没找到\n";
// count:统计等于2的元素个数
int count_val = std::count(v.begin(), v.end(), 2);
std::cout << "count: 有 " << count_val << " 个值为2的元素\n";
// count_if:统计偶数的个数
int count_if_val = std::count_if(v.begin(), v.end(), [](int x) { return x % 2 == 0; });
std::cout << "count_if: 有 " << count_if_val << " 个偶数\n";
// all_of:是否所有元素都大于0
bool all_positive = std::all_of(v.begin(), v.end(), [](int x) { return x > 0; });
std::cout << "all_of: 所有元素都大于0? " << (all_positive ? "是" : "否") << "\n";
// any_of:是否存在一个大于4的元素
bool any_gt4 = std::any_of(v.begin(), v.end(), [](int x) { return x > 4; });
std::cout << "any_of: 存在大于4的元素? " << (any_gt4 ? "是" : "否") << "\n";
// none_of:是否没有小于0的元素
bool none_negative = std::none_of(v.begin(), v.end(), [](int x) { return x < 0; });
std::cout << "none_of: 没有小于0的元素? " << (none_negative ? "是" : "否") << "\n";
return 0;
}
3. 排序与比较
算法 | 作用 |
---|---|
sort | 对容器元素进行升序排序(默认),时间复杂度 O(n log n) |
stable_sort | 保持相等元素的原始相对顺序的排序(稳定排序) |
min_element | 返回容器中最小元素的迭代器 |
max_element | 返回容器中最大元素的迭代器 |
is_sorted | 检查容器是否已按升序排列(返回 true /false ) |
#include <iostream>
#include <vector>
#include <algorithm> // 包含所有算法
int main() {
std::vector<int> to_sort = { 5, 3, 2, 4, 1 };
std::sort(to_sort.begin(), to_sort.end());
std::cout << "sort: 升序排序后:";
for (int x : to_sort) std::cout << x << " ";
std::cout << "\n";
std::vector<int> stable_vec = { 3, 1, 4, 1, 5, 9, 2 };
std::stable_sort(stable_vec.begin(), stable_vec.end());
std::cout << "stable_sort: 稳定排序后:";
for (int x : stable_vec) std::cout << x << " ";
std::cout << "\n";
auto min_it = std::min_element(to_sort.begin(), to_sort.end());
auto max_it = std::max_element(to_sort.begin(), to_sort.end());
std::cout << "min_element: 最小值是 " << *min_it << "\n";
std::cout << "max_element: 最大值是 " << *max_it << "\n";
bool sorted_check = std::is_sorted(to_sort.begin(), to_sort.end());
std::cout << "is_sorted: to_sort 是否已升序排序? " << (sorted_check ? "是" : "否") << "\n";
}
4. 删除与替换
算法 | 作用 |
---|---|
remove | 删除容器中所有等于指定值的元素(需配合 erase 真正删除) |
remove_if | 删除容器中满足谓词条件的元素(需配合 erase ) |
unique | 删除相邻重复元素(需先排序才能删除所有重复元素) |
replace | 将容器中所有等于指定值的元素替换为新值 |
replace_if | 将满足谓词条件的元素替换为新值 |
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> data = {1, 2, 2, 3, 4, 4, 4, 5};
// remove:删除所有值为 2 的元素(需配合 erase)
std::vector<int> r1 = data;
r1.erase(std::remove(r1.begin(), r1.end(), 2), r1.end());
std::cout << "remove 2 后: ";
for (int x : r1) std::cout << x << " ";
std::cout << "\n";
// remove_if:删除所有偶数(需配合 erase)
std::vector<int> r2 = data;
r2.erase(std::remove_if(r2.begin(), r2.end(), [](int x) {
return x % 2 == 0;
}), r2.end());
std::cout << "remove_if 删除偶数后: ";
for (int x : r2) std::cout << x << " ";
std::cout << "\n";
// unique:删除相邻重复元素(不去重所有重复值)
std::vector<int> r3 = data;
auto last = std::unique(r3.begin(), r3.end());
r3.erase(last, r3.end());
std::cout << "unique 删除相邻重复后: ";
for (int x : r3) std::cout << x << " ";
std::cout << "\n";
// 如果要删除所有重复项,需先 sort 再 unique:
std::vector<int> r4 = data;
std::sort(r4.begin(), r4.end());
r4.erase(std::unique(r4.begin(), r4.end()), r4.end());
std::cout << "排序后再 unique(删除所有重复): ";
for (int x : r4) std::cout << x << " ";
std::cout << "\n";
// replace:将所有 4 替换成 99
std::vector<int> r5 = data;
std::replace(r5.begin(), r5.end(), 4, 99);
std::cout << "replace 将 4 替换为 99: ";
for (int x : r5) std::cout << x << " ";
std::cout << "\n";
// replace_if:将所有大于 3 的元素替换为 -1
std::vector<int> r6 = data;
std::replace_if(r6.begin(), r6.end(), [](int x) {
return x > 3;
}, -1);
std::cout << "replace_if 将 >3 的元素替换为 -1: ";
for (int x : r6) std::cout << x << " ";
std::cout << "\n";
return 0;
}
5. 集合操作(进阶)
算法 | 作用 |
---|---|
set_union | 求两个有序容器的并集,结果保存到目标容器 |
set_intersection | 求两个有序容器的交集,结果保存到目标容器 |
includes | 判断一个有序容器是否包含另一个有序容器的所有元素(子集判断) |
merge | 合并两个有序容器的元素,生成一个新的有序容器 |
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
// 两个有序容器(可以是 set, vector, array 等)
std::vector<int> set1 = {1, 3, 5, 7, 9};
std::vector<int> set2 = {3, 4, 5, 6, 7};
// set_union:求并集
std::vector<int> union_result;
std::set_union(set1.begin(), set1.end(), set2.begin(), set2.end(), std::back_inserter(union_result));
std::cout << "set_union: 并集结果:";
for (int x : union_result) std::cout << x << " ";
std::cout << "\n";
// set_intersection:求交集
std::vector<int> intersection_result;
std::set_intersection(set1.begin(), set1.end(), set2.begin(), set2.end(), std::back_inserter(intersection_result));
std::cout << "set_intersection: 交集结果:";
for (int x : intersection_result) std::cout << x << " ";
std::cout << "\n";
// includes:判断 set1 是否包含 set2(子集判断)
bool is_included = std::includes(set1.begin(), set1.end(), set2.begin(), set2.end());
std::cout << "includes: set1 是否包含 set2? " << (is_included ? "是" : "否") << "\n";
// merge:合并两个有序容器
std::vector<int> merge_result;
std::merge(set1.begin(), set1.end(), set2.begin(), set2.end(), std::back_inserter(merge_result));
std::cout << "merge: 合并后的结果:";
for (int x : merge_result) std::cout << x << " ";
std::cout << "\n";
return 0;
}
备注:std:distance的使用
-
std::distance
适用于所有迭代器类型。对于 随机访问迭代器(如vector
或array
的迭代器),时间复杂度是 O(1);而对于 双向迭代器 或 输入迭代器(如list
),时间复杂度是 O(n),因为需要遍历元素计算距离。 -
它 不修改容器内容,只会计算距离。
#include <iostream>
#include <vector>
#include <iterator> // 引入 std::distance
int main() {
std::vector<int> vec = {10, 20, 30, 40, 50};
auto start = vec.begin(); // 起始迭代器
auto end = vec.end(); // 结束迭代器
// 计算迭代器之间的距离
std::cout << "Distance between start and end: "
<< std::distance(start, end) << std::endl;
// 计算一个迭代器到另一个迭代器的距离
auto first = vec.begin();
auto second = first + 3; // 指向第四个元素
std::cout << "Distance between first and second: "
<< std::distance(first, second) << std::endl;
return 0;
}