我有一个任务来读取文件并输出平均测试分数。如何在C++中获得平均值?
这很简单,但我不喜欢如何平均完成。
average = (test1 + test2 + test3 + test4 + test5)/5.0;
有没有办法让它除以测试分数?我在书中或谷歌找不到这样的东西。像
average = (test + test + test + test)/ntests;
我有一个任务来读取文件并输出平均测试分数。如何在C++中获得平均值?
这很简单,但我不喜欢如何平均完成。
average = (test1 + test2 + test3 + test4 + test5)/5.0;
有没有办法让它除以测试分数?我在书中或谷歌找不到这样的东西。像
average = (test + test + test + test)/ntests;
如果你有一个向量或数组中的值,只需使用std::accumulate
从<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();
详细说明@RiaD的说法:当你用C(++)分割整数时,它默认只使用整数运算 - 例如除法结果被截断,小数点后没有数据。如果你的数据集的值足够大,那么这个问题不会太大,但是当处理较小的数字时,你不想失去这个精度,这可能导致0.75变成一个单位0. – 2013-04-26 16:43:41
Shouldn'这是一个'0'。而不是'0'?因为如果您将范围(-0.5,0.5)中的数字相加,没有点将保持为零。 – ikku100 2015-06-29 06:27:09
步骤1.通过迭代(如果你想完成)或递归(如果你想成为勇敢)将所有的考试成绩到一个数组(如果你想简单和速度),或一个链接的东西列表(如果你想要灵活性,但速度很慢)
第2步。遍历数组/列表直到达到最终;随时添加每个单元格/节点的内容。继续计数当前所在的细胞/节点。
第3步。取第一个变量的总和除以第二个变量,它跟踪你的位置。这将产生平均值。
您还可以计算平均使用可变数量的参数。这个函数的原理是将未知数量的参数存储在堆栈中,并且我们可以将它们带走。
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
}
而且,您可以使用此功能,如:
double av1 = average(5, 3.0, 1.5, 5.0, 1.0, 2.0);
double av2 = average(2, 3.0, 1.5);
但参数的数量必须与n相匹配。
请注意此代码。它不保证p按照您的期望工作,因为您依赖于实现细节。至少在64位机器上,有些参数是通过参数传递的,这些代码不起作用。要正确实施,请查看va_start和co。同样在C++ 11中,也有可用的可变模板。 – MJD 2012-02-18 06:43:23
这是我通过指定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();
}
我与测试了它的客户端代码是这样
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();});
想知道,为什么没有人提到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;
}
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...);
}
我无法写它,所以它的自动演绎返回类型。 当我尝试我得到奇怪的结果为average(-2)
。
如果不知道,直到你读取输入的测试次数,你需要一个循环做的* N *数的平均值。 – FrustratedWithFormsDesigner 2012-02-17 19:23:53
步骤0:将其移至堆栈溢出。在这里脱离主题。 – 2012-02-17 19:27:32
优秀的问题和出色的观察。硬编码'5'是a)魔术,b)多余。 – 2012-02-17 19:46:04