Part4:算法(三)

  • rule37:用accumulate或for_each来做区间统计
    count函数能够告诉你区间有多少个等于某个值的元素,而count_if告诉你有多少个元素满足一个判断式。区间的最大值和最小值可以通过min_element和max_element获得。
    有时,你需要自己定义对区间的统计信息,比如求和一个区间的元素和,对一个容器中的字符串长度求和。

accumulate函数存在于numeric中。accumulate存在两种形式。
如下:

    list<double> ld;
    ld.push_back(20);
    ld.push_back(1.1);
    double sum = accumulate(ld.begin(),ld.end(),0.0);

注意初始值指定为0.0,这很重要。0.0的类型是double,所以accumulate内部使用了一个double类型的变量来存储计算的和。写成0的话就会发生强制转换,导致失掉精度。

accumulate还有一种形式,它带有一个初始值和一个任意的统计函数,使用方法如下:

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


//测试代码
    set<string> ss;
    ss.insert("123456789");
    ss.insert("abc");
    ss.insert("def");
    string::size_type length = accumulate(ss.begin(),ss.end(),0,stringLenthSum);

size_type 的类型其实和size_t一样。也可以与int直接转换。length 的结果为15。
计算数值区间的积更简单,我们不用写自己的乘积函数,我们可以使用标准的multiplies仿函数类:

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

下面我贴一段使用仿函数类的代码,实现计算一个区间的点集合的平均值,这一算法,仿函数在以后会提到。我们先有一个直观的感受。


struct Point
{
    double x;
    double y;
    Point(double x,double y)
    {
        this->x = x;
        this->y = y;
    }
};

class PointAverage:public unary_function<Point,void>{

private:
    size_t numPoints;
    double xSum;
    double ySum;
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);
    }

};

//调用函数
    list<Point> Ip;
    Ip.push_back(Point(1,2));
    Ip.push_back(Point(5,2));
    Point avg = for_each(Ip.begin(), Ip.end(), PointAverage()).result();

这里写图片描述
这就是仿函数类的作用。for_each返回一个函数对象,我们可以从这个对象中提取想要的统计信息。在C++中,也就意味着我们必须给仿函数类添加一个成员函数。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值