用accumulate或for_each来统计区间

一、accumulate用法

1、求一个区间的和、积(默认)

// 建立一个list,放一些double进去

list<double> ld;                                                
... 

// 计算它们的和,从0.0开始                                                   
double sum = accumulate(ld.begin(), Id.end(), 0.0);             
                                                        
在本例中,注意初始值指定为0.0,不是简单的0。这很重要。0.0的类型是double,所以accumulate内部使用了一个double类型的变量来存储计算的和。


如果这么写这个调用:

// 计算它们的和,从0开始;这不正确!
double sum = accumulate(ld.begin(), Id.end(), 0);               
                                                        
如果初始值是int 0,所以accumulate内部就会使用一个int来保存它计算的值。那个int最后变成accumulate的返回值,而且它用来初始化和变量。这代码可以编译和运行,但和的值可能不对。不是保存真的double的list的和,它可能保存了所有的double加起来的结果,但每次加法后把结果转换为一个int。


accumulate只需要输入迭代器,所以你甚至可以使用istream_iterator和istreambuf_iterator。

// 打印cin中那些int的和

cout << "The sum of the ints on the standard input is"        
                << accumulate(istream_iterator<int>(cin), istream_iterator<int>(),  0);


2、自定义求和方式

比如,考虑怎么使用accumulate来计算容器中的字符串的长度和。

string::size_type                                       
stringLengthSum(string::size_type sumSoFar, const string& s){
        return sumSoFar + s.size();
}


这个函数的函数体非常简单,但你可能发现自己陷于string::size_type的出现。不要那样。每个标准STL容器都有一个typedef叫做size_type,那是容器计量东西的类型。比如,这是容器的size函数的返回类型。对于所有的标准容器,size_type必须是size_t,对于标准容器,你可以把Container::size_type看作size_t写法的一个奇异方式。


 // 建立字符串的容器, 进行一些操作

set<string> ss;                                
...         

// 把lengthSum设为对ss中的每个元素调用stringLengthSum的结果

//使用0作为初始统计值                                   
string::size_type lengthSum = accumulate(ss.begin(), ss.end(),0, stringLengthSum);    
3、求积   

// 建立float的容器

vector<float> vf;      

 // 进行一些操作                               

...        

// 把product设为对vf中的每个元素调用multiplies<float>(标准乘积仿函数类)的结果,

//用1.0f 作为初始统计值                                      

float product =  accumulate(vf.begin(), vf.end(), 1.0f,  multiplies<float>());    

4、求平均值    

寻找point的区间的平均值


struct Point {
        Point(double initX, double initY): x(initX), y(initY) {}
        double x, y;
};    


class PointAverage : public binary_function<Point, Point, Point> {        
public:
        PointAverage(): numPoints(0), xSum(0), ySum(0) {}
        const Point operator()( const Point& avgSoFar,  const Point& p ) {
                ++numPoints;
                xSum += p.x;
                ySum += p.y;
                return Point(xSum/numPoints, ySum/numPoints);
        }


private:
        size_t numPoints;
        double xSum;
        double ySum;
};    


list<Point> lp;
...

// 对Ip中的point求平均值
Point avg =  accumulate(lp.begin(), lp.end(), Point(0, 0),  PointAverage());                    

二、for_each用法    

// 同上

struct Point {...);                                     
class PointAverage : public unary_function<Point, void> {           
public:
        PointAverage(): xSum(0), ySum(0), numPoints(0) {}
        void operator()(const Point& p){
                ++numPoints;
                xSum += p.x;
                ySum += p.y;
        }
        Point result() const {
                return Point(xSum/numPoints, ySum/numPoints);
        }


private:
        size_t numPoints;
        double xSum;
        double ySum;
};


list<Point> Ip;
...
Point avg = for_each( lp.begin(), lp.end(), PointAverage() ).result;

                     

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值