时间:2022-09-27 11:10:23 | 栏目:C代码 | 点击:次
以下算法均包含在头文件 numeric 中
该函数可以把一个范围内的序列从给定的初始值开始累加
先看用法。
例:
假设我需要一个长度为10,从5开始递增的序列
vector<int> a(10); iota(begin(a), end(a), 5); for (auto x : a) { cout << x << " "; }
输出:
5 6 7 8 9 10 11 12 13 14
这样就可以很方便的创建一个递增的序列,而不用使用for循环
此外,该函数是使用连续的支持 operator++()的 T 类型值填充序列
也就是说double类型也可以使用,string类型也可以使用。
只要是重载了++运算符的类型都可以使用。
曾经在算法比赛中看见别人使用accumulate函数计算出了一个数组的和。
觉得特别的优雅,像这样:
vector<int> a(10); iota(begin(a), end(a), 1); cout << accumulate(begin(a), end(a), 0) << "\n"; // 计算从1加到10的和,从0开始加
输出:
55
从那天起,每当我要求一个序列的和的时候,我都会使用这个方法...
但是今天,当我看到accumulate的源码之后:
template <class InputIterator, class T> T accumulate (InputIterator first, InputIterator last, T init) { while (first!=last) { init = init + *first; // or: init=binary_op(init,*first) for the binary_op version ++first; } return init; }
注意看这里:
哇哦,它竟然还支持二元仿函数,详解C++ functional库中的仿函数使用方法
于是,我有了一个大胆的想法。
求一个数组的乘积
vector<int> a(10); iota(begin(a), end(a), 1); cout << accumulate(begin(a), end(a), 1, multiplies<int>()) << "\n"; // 计算从1加到10的乘积,从1开始乘
输出:
3628800
同理,还可以求数组的减,数组的除,数组的模?
这个函数可以用来求前缀和,前缀和指一个数组的某下标之前的所有数组元素的和(包含其自身)。
例如,1、2、3、4、5的前缀和数组为 1 3 6 10 15
vector<int> a(5); iota(begin(a), end(a), 1); partial_sum(begin(a), end(a), begin(a)); // 求a的前缀和,赋值给a数组(第三个参数) for (auto x : a) { cout << x << " "; }
输出:
1 3 6 10 15
有了上一个函数的经验,我们还可以求一个数组的前缀乘、除等
例:
partial_sum(begin(a), end(a), begin(a), multiplies<int>());
输出:
1 2 6 24 120
这个函数可以对一个序列里相邻两个元素进行运算,通过differerce这个词可以看出来,默认是计算相邻两元素的差
vector<int> a{1, 4, 5, 100, 40}; adjacent_difference(begin(a), end(a), begin(a)); // 求a数组相邻元素的差,赋值给a数组(第三个参数) for (auto x : a) { cout << x << " "; }
输出:
1 3 1 95 -60
今天我想计算相邻两元素的乘积
adjacent_difference(begin(a), end(a), begin(a), multiplies<int>());
输出:
1 4 20 500 4000
这个函数默认情况下可以求序列中每个元素的内积之和:
vector<int> a(3); iota(begin(a), end(a), 1); cout << inner_product(begin(a), end(a), begin(a), 10) << "\n"; // 从初值10开始加上序列各元素的内积
输出:
24
还可以用来求两个序列元素两两相乘再相加的结果
vector<int> a{1, 2, 3}; vector<int> b{2, 3, 4}; // 1 * 2 + 2 * 3 + 3 * 4 cout << inner_product(begin(a), end(a), begin(b), 0) << "\n";
输出:
20
此外,还可以通过仿函数来替代上述的两个操作符 + 和 *
vector<int> a{1, 2, 3}; vector<int> b{2, 3, 4}; cout << inner_product(begin(a), end(a), begin(b), 1 , multiplies<int>(), minus<int>()) << "\n"; // 原来的加法 + // 原来的乘法 * // 计算 (1 - 2) * (2 - 3) * (3 - 4) = -1
输出:
-1