zoukankan      html  css  js  c++  java
  • C++STL 求和:accumulate 【转】

    该算法在numeric头文件中定义。

    accumulate()的原型为(文件取自DEV-C++编译器):

     1 template<typename _InputIterator, typename _Tp, typename _BinaryOperation>
     2  _Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init,
     3             _BinaryOperation __binary_op)
     4  {
     5      // concept requirements
     6      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
     7     __glibcxx_requires_valid_range(__first, __last);
     8  
     9     for ( ; __first != __last; ++__first)
    10        __init = __binary_op(__init, *__first);
    11     return __init;
    12  }

    假设vec是一个int型的vector对象,下面的代码:

    //sum the elements in vec starting the summation with the value 42
    int sum = accumulate(vec.begin() , vec.end() , 42);

    将sum设置为vec的元素之和再加上42。

    accumulate带有三个形参:头两个形参指定要累加的元素范围,第三个形参则是累加的初值

    accumulate函数将它的一个内部变量设置为指定的初始值,然后在此初值上累加输入范围内所有元素的值。accumulate算法返回累加的结果,其返回类型就是其第三个实参的类型

     用于指定累加起始值的第三个参数是必要的,因为accumulate对将要累加的元素类型一无所知,除此之外,没有别的办法创建合适的起始值或者关联的类型。 

    accumulate对要累加的元素类型一无所知,这个事实有两层含义。首先,调用该函数时必需传递一个初始值,否则,accumulate将不知道使用什么初始值。其次,容器内的元素类型必须与第三个实参的类型匹配,或者可转换为第三个实参的类型。在accumulate内部,第三个实参用作累加的起点;容器内的元素按顺序连续累加到综合之中。因此,必须能够将元素类型加到总和类型上。

    假定V是vector<double>类型的对象,则调用accumulate(v.begin() , v.end() , 0)是否有错?如果有的话,错在哪里?

    从函数调用上看没有错误。
    调用accumulate函数必须满足的条件包括:容器内的元素类型必须与第三个实参的类型匹配,或者可转换为第三个实参的类型。上述调用中的第三个实参为int类型,而vector对象中的元素的类型为double类型,可以转换为int类型。

    但计算的结果不准确。因为将double类型转换为int类型会截去小数部分,得到的求和结果是各元素的整数部分的和,是一个int类型的值,与实际的元素值总和相比会有比较大的误差。

    考虑下面的例子,可以使用accumulate把string型的vector容器中的元素连接起来:

    //concatenate elements from V and store in sum
    string sum = accumulate(v.begin() , v.end() , string(" "));

    这个函数调用的效果是:从空字符串开始,把vec里的每个元素连接成一个字符串。

    下面让我们用一个具体事例来说明:用accumulate统计vector<int>容器对象中的元素之和。

     1 //读取一系列int型数据,并将它们存储到vector对象中,
     2 //然后使用algorithm头文件中定义的名为accumulate的函数,
     3 //统计vector对象中的元素之和
     4 #include<iostream>
     5 #include<vector>
     6 #include<numeric>
     7 using namespace std;
     8 
     9 int main()
    10 {
    11     int ival;
    12     vector<int> ivec;
    13 
    14     //读入int型数据并存储到vector对象中,直至遇到文件结束符
    15     cout<<"Enter some integers(Ctrl+z to end): "<<endl;
    16     while(cin >> ival)
    17         ivec.push_back(ival);
    18 
    19     //使用accumulate函数统计vector对象中的元素之和并输出结果
    20     cout<<"summation of elements in the vector: "
    21         <<accumulate(ivec.begin() , ivec.end() , 0)  //统计vector对象中的元素之和
    22         <<endl;
    23 
    24     return 0;
    25 }

    accumulate()可以用来直接计算数组或者容器中C++内置数据类型,但是对于自定义数据类型,我们就需要自己动手写一个类来实现自定义数据的处理,然后让它作为accumulate()的第四个参数。

    假设自定义数据类型为:

    1 struct Student  
    2 {  
    3       string name;   // 学生姓名  
    4        int total;      // 四级分数  
    5 };  
    那么我们可能要定义如下列的类:

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <numeric>
     4 #include <vector>
     5 #include <string>
     6 using namespace std;
     7 
     8 struct Student
     9 {
    10        string name;
    11        int total;
    12 };
    13 
    14 class PS{
    15  public:
    16         int operator()(int t1,const Student& t2)
    17         {
    18             return (t1 + t2.total);
    19         }
    20         
    21 };
    22 
    23 int main()
    24 {
    25     Student student[3]={
    26             {"hicjiajia",10},
    27             {"sijikaoshi",20},
    28             {"what",40}
    29             };
    30     
    31     int sum=accumulate(&student[0],&student[3],0,PS());
    32     cout<<sum<<endl;
    33     
    34     system("pause");
    35     return 0;
    36 }


    文末附:资料链接
  • 相关阅读:
    因数最多的数
    剪枝策略
    计蒜客 引爆炸弹(DFS、并查集)
    计蒜客 方程的解数(DFS)
    计蒜客 数独(DFS)
    计蒜客 王子救公主(DFS)
    kuangbin专题 专题九 连通图 POJ 3694 Network
    2019 ICPC Asia Nanjing Regional K. Triangle
    HDU 1875 畅通工程再续
    还是畅通工程 HDU
  • 原文地址:https://www.cnblogs.com/Kiven5197/p/5549827.html
Copyright © 2011-2022 走看看