遍历算法
遍历算法的核心目的:按规则访问容器中的每个 / 部分元素,并执行指定操作;
核心头文件:#include <algorithm>
迭代器区间:统一遵循「左闭右开」原则([first, last)),即包含 first,不包含 last。
for_each最常用的遍历算法
- 函数原型:for_each(开始迭代器,结束迭代器,一元可调用对象(函数指针/Lambda/仿函数,参数为单个元素));返回值为传入的可调用对象。
- 功能:遍历
[first, last)区间内的每一个元素,对每个元素执行自定义操作(无返回值,仅执行「动作」),是 STL 最基础、最灵活的遍历算法。
函数使用
- 普通函数作为操作
#include <vector>
#include <algorithm>
// 普通函数
void printInt(int val)
{
cout << val << " ";
}
int main()
{
vector<int> v = { 5, 10, 15, 20, 25 };
// 普通函数,打印遍历出来的元素
for_each(v.begin(), v.end(), printInt);
// 输出结果5 10 15 20 25
return EXIT_SUCCESS;
};
如果在遍历时需要修改元素,则可以传入元素的引用:
// 普通函数
void printInt(int val)
{
cout << val << " ";
}
// 普通函数,参数为引用类型
void addTen(int& val)
{
val += 10;
}
int main()
{
vector<int> v = { 5, 10, 15, 20, 25 };
// 遍历并修改元素
for_each(v.begin(), v.end(), addTen);
// 普通函数,打印遍历出来的元素
for_each(v.begin(), v.end(), printInt);
// 输出结果15 20 25 30 35
return EXIT_SUCCESS;
};
- 仿函数作为操作
// 仿函数
struct PrintInt {
// 重载()运算符
void operator()(int val) const
{
cout << val << " " << endl;
}
};
int main()
{
vector<int> v = { 5, 10, 15, 20, 25 };
// 仿函数,打印遍历出来的元素
for_each(v.begin(), v.end(), PrintInt());
// 输出结果5 10 15 20 25
return EXIT_SUCCESS;
};
- lambda表达式作为操作
int main()
{
vector<int> v = { 5, 10, 15, 20, 25 };
// lambda表达式,遍历并修改元素
for_each(v.begin(), v.end(), [](int& val) {
val *= 2;
});
// lambda表达式,打印遍历出来的元素
for_each(v.begin(), v.end(), [](int val) {
cout << val << " ";
});
// 输出结果10 20 30 40 50
cout << endl;
return EXIT_SUCCESS;
};
注意点
修改元素必须用引用:Lambda / 函数参数需写 int&(而非 int),否则仅操作元素副本,原容器无变化; 自定义类型用 const&:遍历自定义类型时,参数用 const Person& 避免不必要的拷贝,提升效率; 不支持提前终止:for_each 会强制遍历完整个区间,无法像普通 for 循环那样用 break 退出; 并行遍历:C++17 后可加执行策略(如 std::execution::par)实现多线程并行遍历,适合大数据量场景。
进阶遍历算法
for_each_n(c++ 17新增)
仅遍历区间的前 n 个元素(解决 for_each 必须遍历全部的问题)。
vector<int> v = { 5, 10, 15, 20, 25 };
// 仅遍历前3个元素
for_each_n(v.begin(), 3, [](int val) {
cout << val << " ";
});
// 输出结果5 10 15
cout << endl;
transform(遍历 + 变换)
遍历原区间,对每个元素执行变换操作,并将结果存入新区间(或原区间),是「遍历 + 输出」的组合算法。
核心区别 vs for_each
for_each:侧重「执行操作」(如打印、修改原元素),无返回值;transform:侧重「生成新值」(如元素 ×2 后存入新容器),必须指定输出迭代器。
vector<int> v = { 5, 10, 15, 20, 25 };
vector<int> v1(v.size());
transform(v.begin(), v.end(), v1.begin(), [](int val) {
return val * 2;
});
for_each(v1.begin(), v1.end(), [](int val) {cout << val << ","; });
// 输出结果10,20,30,40,50
return EXIT_SUCCESS;
遍历+条件判断
遍历区间,判断元素是否满足指定条件(返回 bool),属于「遍历 + 判断」的简化算法。
all_of所有元素都满足条件 → true
any_of至少一个元素满足条件 → true
none_of没有元素满足条件 → true
vector<int> v = { 5, 10, 15, 20, 25 };
// 所有元素都大于5,输出结果0
bool ret = all_of(v.begin(), v.end(), [](int val) {return val > 5; });
cout << ret << endl;
// 至少一个元素大于5,输出结果1
ret = any_of(v.begin(), v.end(), [](int val) {return val > 5; });
cout << ret << endl;
// 没有1个元素大于5,输出结果0
ret = none_of(v.begin(), v.end(), [](int val) {return val > 5; });
cout << ret << endl;