用accumulate或for_each来统计区间

本文详细介绍了C++ STL库中的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;

                     

F. Attraction Theory time limit per test2 seconds memory limit per test256 megabytes Taylor Swift - Love Story (Taylor's Version) ⠀ There are 𝑛 people in positions 𝑝1,𝑝2,…,𝑝𝑛 on a one-dimensional coordinate axis. Initially, 𝑝𝑖=𝑖 for each 1≤𝑖≤𝑛. You can introduce an attraction at some integer coordinate 𝑥 (1≤𝑥≤𝑛), and then all the people will move closer to the attraction to look at it. Formally, if you put an attraction in position 𝑥 (1≤𝑥≤𝑛), the following changes happen for each person 𝑖 (1≤𝑖≤𝑛): if 𝑝𝑖=𝑥, no change; if 𝑝𝑖<𝑥, the person moves in the positive direction, and 𝑝𝑖 is incremented by 1; if 𝑝𝑖>𝑥, the person moves in the negative direction, and 𝑝𝑖 is decremented by 1. You can put attractions any finite number of times, and in any order you want. It can be proven that all positions of a person always stays within the range [1,𝑛], i.e. 1≤𝑝𝑖≤𝑛 at all times. Each position 𝑥 (1≤𝑥≤𝑛), has a value 𝑎𝑥 associated with it. The score of a position array [𝑝1,𝑝2,…,𝑝𝑛], denoted by 𝑠𝑐𝑜𝑟𝑒(𝑝), is ∑𝑛𝑖=1𝑎𝑝𝑖, i.e. your score increases by 𝑎𝑥 for every person standing at 𝑥 in the end. Over all possible distinct position arrays 𝑝 that are possible with placing attractions, find the sum of 𝑠𝑐𝑜𝑟𝑒(𝑝). Since the answer may be large, print it modulo 998244353. Input Each test contains multiple test cases. The first line contains the number of test cases 𝑡 (1≤𝑡≤104). The description of the test cases follows. The first line of each test case contains a single integer 𝑛 (1≤𝑛≤2⋅105). The second line of each test case contains 𝑛 integers — 𝑎1,𝑎2,…,𝑎𝑛 (1≤𝑎𝑖≤109) It is guaranteed that the sum of 𝑛 over all test cases does not exceed 2⋅105. Output For each test case, output a single line containing an integer: the sum of 𝑠𝑐𝑜𝑟𝑒(𝑝) over all possible distinct position arrays 𝑝 that are possible with placing attractions, modulo 998244353. Example inputCopy 7 1 1 2 5 10 3 1 1 1 4 1 1 1 1 4 10 2 9 7 5 1000000000 1000000000 1000000000 1000000000 1000000000 8 100 2 34 59 34 27 5 6 outputCopy 1 45 24 72 480 333572930 69365 Note In the first test case, the only possible result is that person 1 stays at 1. The score of that is 𝑎1=1. In the second test case, the following position arrays [𝑝1,𝑝2] are possible: [1,2], score 15; [1,1], score 10; [2,2], score 20. The sum of scores is 15+10+20=45. In the third test case, the following position arrays [𝑝1,𝑝2,𝑝3] are possible: [1,1,1]; [1,1,2]; [1,2,2]; [1,2,3]; [2,2,2]; [2,2,3]; [2,3,3]; [3,3,3]. Each has a score of 3, and thus the total sum is 24.解决这道题,用c++
最新发布
09-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值