C++ 如何用迭代器和lambda函数计算标准差

C++ 如何用迭代器和lambda函数计算标准差,c++,lambda,iterator,C++,Lambda,Iterator,在了解到可以计算存储在std::vectordata中的数据平均值后,可以通过以下方式完成: void calculate_mean(std::vector<std::vector<double>>::iterator dataBegin, std::vector<std::vector<double>>::iterator dataEnd, std::vector&

在了解到可以计算存储在
std::vectordata
中的数据平均值后,可以通过以下方式完成:

void calculate_mean(std::vector<std::vector<double>>::iterator dataBegin,
                    std::vector<std::vector<double>>::iterator dataEnd, 
                    std::vector<double>& rowmeans) {
    auto Mean = [](std::vector<double> const& vec) {
                    return std::accumulate(vec.begin(), vec.end(), 0.0) / vec.size(); };
    std::transform(dataBegin, dataEnd, rowmeans.begin(), Mean);
}
无效计算平均值(标准::向量::迭代器数据域, std::vector::迭代器dataEnd, 标准::矢量和行平均数){ 自动平均=[](标准::向量常量和向量){ 返回std::accumulate(vec.begin(),vec.end(),0.0)/vec.size();}; std::transform(dataegin,dataEnd,rowmeans.begin(),Mean); } 我做了一个函数,它取数据向量迭代器的开始和结束来计算平均值,
std::vector
是我存储结果的地方。 我的第一个问题是,在处理向量时,如何处理函数的返回值。我的意思是,在本例中,我创建了一个别名,并以这种方式修改了在调用此函数之前初始化的向量,因此没有复制回来,这很好。这是一个好的编程实践吗

其次,我的主要问题是,如何调整此函数,以便可以以类似的方式计算每行的标准偏差。我真的很努力,但它只会给一个巨大的混乱,没有什么工作正常。所以,如果有人马上看到了如何做到这一点,我会很高兴,因为我有一个见解。多谢各位

编辑:解决方案

这是我对这个问题的解决方案。给定一个
std::vector数据(行,std::vector(列))
,其中数据存储在行中。以下函数同时计算每行的样本标准偏差

auto begin = data.begin();
auto end = data.end();
std::vector<double> std;
std.resize(data.size());

void calculate_std(std::vector<std::vector<double>>::iterator dataBegin,
                   std::vector<std::vector<double>>::iterator dataEnd,
                   std::vector<double>& rowstds){

    auto test = [](std::vector<double> const& vec) {
                    double sum = std::accumulate(vec.begin(), vec.end(), 0.0);
                    double mean = sum / vec.size(); 
                    double stdSum = 0.0;
                    auto Std = [&](const double x) { stdSum += (x - mean) * (x - mean); }; 
                    std::for_each(vec.begin(), vec.end(), Std);
                    return sqrt(stdSum / (vec.size() - 1)); 
    };
    std::transform(dataBegin, dataEnd, rowstds.begin(), test);

}  
auto begin=data.begin();
自动结束=data.end();
std::向量std;
std.resize(data.size());
void calculate_std(std::vector::iterator dataegin,
std::vector::迭代器dataEnd,
std::矢量和行(std){
自动测试=[](标准::向量常量和向量){
double sum=std::累加(vec.begin(),vec.end(),0.0);
双平均值=总和/向量大小();
双标准差=0.0;
自动标准=[&](常数双x){stdSum+=(x-平均值)*(x-平均值);};
std::for_each(vec.begin()、vec.end()、std);
返回sqrt(stdSum/(向量大小()-1));
};
std::transform(dataegin、dataEnd、rowstds.begin()、test);
}  

我测试了一下,效果很好。因此,如果有人有一些改进的建议,请让我知道。这段代码在性能方面是否良好?

您会发现,编写函数时通常先使用输入参数,然后使用输入/输出参数。 输出参数(用函数的返回值写入)通常是指向数据的指针或引用。 从这个角度来看,你的解决方案似乎是完美的

资料来源:

我的意思是,在本例中,我创建了一个别名,并以这种方式修改了在调用此函数之前初始化的向量,因此没有复制回来,这很好。这是一个好的编程实践吗

否,您应该使用本地
向量
变量并按值返回。任何值得使用的编译器,以及任何符合C++11标准的编译器,如果出于任何原因不能完全删除复制/移动,都需要执行移动


您编写的代码对调用方施加了不明显的额外要求。例如,
rowmeans
必须包含足够的元素来存储平均值或未定义的行为结果。

对于第二部分-“我非常努力,但它只会造成一个巨大的混乱,没有正常工作。”-向我们展示您的尝试。@T.C我用我的一次尝试进行了编辑,以找出它是如何工作的。这真是一团糟,所以我想我还是不发布它为好。我投票结束这个问题,因为它是关于代码审查的,属于codereview.stackexchange.com