如何在 C++ 中获得平均值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9334185/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get an average in C++?
提问by toby yeats
I have an assignment to read a file and output the average test scores.
我有一个任务是读取文件并输出平均测试分数。
It is pretty simple but I don't like how the average is done.
这很简单,但我不喜欢平均值的计算方式。
average = (test1 + test2 + test3 + test4 + test5) / 5.0;
Is there a way to just have it divide by the number of test scores? I couldn't find anything like this in the book or from google. Something like
有没有办法让它除以考试分数?我在书中或谷歌上都找不到这样的东西。就像是
average = (test + test + test + test) / ntests;
回答by Charles Salvia
If you have the values in a vector or an array, just use std::accumulate
from <numeric>
:
如果您有向量或数组中的值,只需使用std::accumulate
from <numeric>
:
std::vector<double> vec;
// ... fill vec with values (do not use 0; use 0.0)
double average = std::accumulate(vec.begin(), vec.end(), 0.0) / vec.size();
回答by World Engineer
Step 1. Via iteration (if you want to be done) or recursion (if you want to be brave) place all test scores into an array (if you want simplicity and speed) or a linked list (if you want flexibility but slow)
步骤 1. 通过迭代(如果你想完成)或递归(如果你想勇敢)将所有测试分数放入一个数组(如果你想要简单和速度)或一个链表(如果你想要灵活性但速度慢)
Step 2. Iterate through the array/list until you reach the end; adding the contents of each cell/node as you go. Keep a count of what cell/node you are currently at as you go as well.
步骤 2. 遍历数组/列表,直到到达末尾;随时添加每个单元格/节点的内容。在您进行时,也要记下您当前所在的单元/节点。
Step 3. Take the sum from the first variable and divide it by the second variable that kept track of where you were. This will yield the mean.
步骤 3. 将第一个变量的总和除以记录您所在位置的第二个变量。这将产生平均值。
回答by prestokeys
Here is my generalization of getting the average of the elements of a container by specifying a lambda function to obtain each value and then add up:
这是我通过指定 lambda 函数获取每个值然后相加来获取容器元素平均值的概括:
template <typename ForwardIterator, typename F>
double inline averageOf (ForwardIterator first, ForwardIterator last, F function) {
std::vector<typename std::result_of<F(typename ForwardIterator::value_type)>::type> values;
while (first != last) {
values.emplace_back (function(*first));
++first;
}
return static_cast<double>(std::accumulate (values.begin(), values.end(), 0)) / values.size();
}
The client code I tested it with goes like
我测试它的客户端代码就像
const std::list<CharmedObserver*> devotees =
charmer->getState<CharmerStateBase>(CHARMER)->getDevotees();
const int averageHitPointsOfDevotees = averageOf (devotees.begin(), devotees.end(),
[](const CharmedObserver* x)->int {return x->getCharmedBeing()->getHitPoints();});
回答by Aleph0
Wondering, why no one mentioned boost::accumulators
. It is not the shortest of the already posted solutions, but can be more easily extended for more general statistical values. Like standard deviation or higher moments.
想知道为什么没有人提到boost::accumulators
。它不是已经发布的解决方案中最短的,但可以更容易地扩展为更一般的统计值。像标准偏差或更高的时刻。
#include <iostream>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <algorithm>
#include <vector>
double mean(const std::vector<double>& values) {
namespace bo = boost::accumulators;
if (values.empty()) return 0.;
bo::accumulator_set<double, bo::stats<bo::tag::mean>> acc;
acc=std::for_each(values.begin(), values.end(), acc);
return bo::mean(acc);
}
int main()
{
std::vector<double> test = { 2.,6.,4.,7. };
std::cout << "Mean: " << mean(test) << std::endl;
std::cout << "Mean: " << mean({}) << std::endl;
return 0;
}
回答by Marek R
C++11 gives nice solution:
C++11 给出了很好的解决方案:
constexpr auto countArguments() -> size_t
{
return 0;
}
template<class T1, class ... Ti>
constexpr auto countArguments(T1, Ti ...xi) -> size_t
{
return 1 + countArguments(xi...);
}
template<class T>
constexpr auto sumAruguments(T x) -> double
{
return x;
}
template<class T1, class ... Ti>
constexpr auto sumAruguments(T1 x1, Ti ...xi) -> double // decltype(x1 + sumAruguments(xi...))
{
return x1 + sumAruguments(xi...);
}
template<class...T>
constexpr auto avarage(T...xi) -> double
{
return sumAruguments(xi...) / countArguments(xi...);
}
I was unable to write it so it auto-deduce return type.
When I tried I get weird result for average(-2)
.
我无法编写它,因此它会自动推断返回类型。当我尝试时,我得到了奇怪的结果average(-2)
。
回答by zifter
You can also calculate average using variable number of arguments. The principle of this a function that an unknown number of arguments is stored in a stack and we can take them.
您还可以使用可变数量的参数计算平均值。这个函数的原理是将未知数量的参数存储在堆栈中,我们可以获取它们。
double average(int n, ...) // where n - count of argument (number)
{
int *p = &n; // get pointer on list of number in stack
p++; // get first number
double *pp = (double *)p; // transformation of the pointer type
double sum = 0;
for ( int i = 0; i < n; pp++, i++ ) //looking all stack
sum+=(*pp); // summarize
return sum/n; //return average
}
And you can using this function like:
您可以使用此功能,例如:
double av1 = average( 5, 3.0, 1.5, 5.0, 1.0, 2.0 );
double av2 = average( 2, 3.0, 1.5 );
But the number of arguments must match with the n.
但是参数的数量必须与 n 匹配。