C++STL中的数值算法(iota、accumulate、adjacent_difference、inner_product、partial_sum)

博客 分享
0 256
张三
张三 2022-04-07 21:57:39
悬赏:0 积分 收藏

C++STL 中的数值算法(iota、accumulate、adjacent_difference、inner_product、partial_sum)

以下算法均包含在头文件 numeric 中

1.iota

该函数可以把一个范围内的序列从给定的初始值开始累加
先看用法。
例:
假设我需要一个长度为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类型也可以使用。
只要是重载了++运算符的类型都可以使用。

2.accumulate

曾经在算法比赛中看见别人使用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
同理,还可以求数组的减,数组的除,数组的模??

3.partial_sum

这个函数可以用来求前缀和,前缀和指一个数组的某下标之前的所有数组元素的和(包含其自身)。
例如,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

4.adjacent_difference

这个函数可以对一个序列里相邻两个元素进行运算,通过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

5.inner_product

  • 这个函数默认情况下可以求序列中每个元素的内积之和:
    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

posted @ 2022-04-07 21:32 Aatrowen 阅读(0) 评论(0) 编辑 收藏 举报
回帖
    张三

    张三 (王者 段位)

    821 积分 (2)粉丝 (41)源码

     

    温馨提示

    亦奇源码

    最新会员