需要用一些灵活的自定义的方式统计区间时可以用accumulate或for_each(accumulate在中)。
accumulate的简单用法:
vector<int> v = {1, 2, 3, 4, 5};
int sum = accumulate(v.begin(), v.end(), 0);//求和 sum=15
需要注意的是,第三个参数为初始值,它的类型需要和统计的类型相同,例如:
vector<double> v = {1.1, 2.2};
int sum = accumulate(v.begin(), v.end(), 0.0);//正确 sum = 3.300000
下面是错误的例子,第三个参数为int 0,函数则以int型保存结果,导致最终sum=3.0,且编译运行正常:
vector<double> v = {1.1, 2.2};
int sum = accumulate(v.begin(), v.end(), 0);//错误! sum = 3.000000
accumulate也可以使用自定义的统计函数,例如求区间的积(使用标准
multiplies仿函数类):
vector<double> v = {1.1, 2.0};
double sum = accumulate(v.begin(), v.end(), 1.0, multiplies<double>());
复杂一些的例子,计算二维点的平均值,Point定义如下:
struct Point
{
Point(double initX, double initY): x(initX), y(initY) {}
double x, y;
};
调用accumulate:
vector<Point> v = {Point(1, 2), Point(3, 2), Point(-2, 4)};
Point avg = accumulate(v.begin(), v.end(), Point(0, 0), PointAverage());
PointAverage是仿函数类的对象,定义如下:
class PointAverage
{
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;
};
用for_each也可以实现同样的功能,调用:
Point avg = for_each(v.begin(), v.end(), PointAverage()).result();
PointAverage代码:
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;
};