C++使用numeric
std::iota
以起始值的连续增量填充一个范围
- 就地填充:直接修改容器中的元素
- 连续递增:从指定值开始,依次递增赋值
- 要求类型支持 :
T必须支持前缀++操作符 - 迭代器要求:至少是前向迭代器(ForwardIterator)
cpp
int main() {
system("chcp 65001");
// 1. 填充 vector,从1开始
std::vector<int> vec(5);
std::iota(vec.begin(), vec.end(), 1);
for (int x : vec) {
std::cout << x << ", ";
}
std::cout << endl;
// 2. 填充数组,从10开始
int arr[5];
std::iota(std::begin(arr), std::end(arr), 10);
for (int x : arr) {
std::cout << x << ", ";
}
std::cout << endl;
// 求和
int sum = std::accumulate(std::begin(arr), std::end(arr), 0);
std::cout << "sum: " << sum << endl;
// 过滤
auto result1 = arr | std::views::filter([](int x) { return x % 2 == 0; })
| std::views::transform([](int x) { return x * x; });
for (int item : result1) {
std::cout << item << ", ";
}
std::cout << endl;
return 0;
}
std::ranges::iota
std::ranges::iota是 C++23 引入的算法 ,用于将递增的值填充到范围中。它等价于传统的std::iota,但使用了 C++20 的范围(Ranges)接口
- 范围友好: 支持直接传入范围对象
- 类型安全: 编译时概念约束确保类型兼容性
- 信息丰富: 返回最终状态信息
- 性能优秀: 线性时间复杂度,常数空间开销
- 向后兼容: 仍然支持传统的迭代器接口
| 特性 | std::iota (C++11) |
std::ranges::iota (C++23) |
|---|---|---|
| 头文件 | <numeric> |
<numeric> |
| 参数 | 迭代器对 + 初始值 | 范围/迭代器对 + 初始值 |
| 返回值 | void | iota_result 结构体 |
| 范围支持 | 无 | 原生支持范围 |
| 约束检查 | 运行时 | 编译时概念约束 |
cpp
int main() {
system("chcp 65001");
// 1. 填充 vector,从1开始
std::vector<int> vec(5);
std::ranges::iota(vec, 1);
for (int x : vec) {
std::cout << x << ", ";
}
std::cout << endl;
// 2. 填充数组,从10开始
int arr[5];
std::ranges::iota(arr, 10);
for (int x : arr) {
std::cout << x << ", ";
}
std::cout << endl;
// 求和
int sum = std::accumulate(std::begin(arr), std::end(arr), 0);
std::cout << "sum: " << sum << endl;
// 过滤
auto result1 = arr | std::views::filter([](int x) { return x % 2 == 0; })
| std::views::transform([](int x) { return x * x; });
for (int item : result1) {
std::cout << item << ", ";
}
std::cout << endl;
return 0;
}
std::accumulate
对一个序列中的所有元素,按顺序进行累积计算,最终返回一个单一结果
cpp
int main() {
system("chcp 65001");
std::vector<int> numbers = { 1, 2, 3, 4, 5 };
// 求和
int result = std::accumulate(numbers.begin(), numbers.end(), 0);
std::cout << "Sum: " << result << endl;
// 使用 fold_left(等价于 accumulate)
result = std::ranges::fold_left(numbers, 0, std::plus{});
std::cout << "Sum: " << result << endl;
// 乘法
result = std::accumulate(numbers.begin(), numbers.end(), 1, std::multiplies{});
std::cout << "Sum: " << result << endl;
result = std::ranges::fold_left(numbers, 1, std::multiplies{});
std::cout << "Sum: " << result << endl;
// 拼接
auto line = std::accumulate(numbers.begin(), numbers.end(), std::string{}, [](std::string a, int b) {return a + std::to_string(b); });
std::cout << "result: " << line << endl;
auto words = numbers | std::views::transform([](int it) {return std::to_string(it); });
line = std::accumulate(words.begin(), words.end(), std::string{});
std::cout << "result: " << line << endl;
line = std::ranges::fold_left(numbers, std::string{}, [](std::string a, int b) {return a + std::to_string(b); });
std::cout << "Sum: " << line << endl;
return 0;
}
std::reduce
一个并行友好的折叠算法 ,用于对序列进行累积计算,与
std::accumulate的关键区别在于:
- 不要求操作顺序(可并行执行)
- 要求操作满足结合律和交换律
- 可能比
accumulate更快(尤其在并行执行时)
| 特性 | std::accumulate |
std::reduce |
|---|---|---|
| 执行顺序 | 严格从左到右 | 任意顺序(可并行) |
| 操作要求 | 无特殊要求 | 必须满足结合律 + 交换律 |
| 并行支持 | ❌ 不支持 | ✅ 支持(通过执行策略) |
| 性能 | 稳定但串行 | 可能更快(并行时) |
| 默认操作 | 加法 | 加法 |