假设我想向用户询问一些整数,然后我想对它们进行一些算术运算(如计算平均值、众数等)。收集数据以便能够对其应用统计函数的最佳和最有效的方法是什么?
中位数和众数更容易从排序的数据中找到。
如果用户将键入数据,则在数组中插入排序是一个不错的选择,因为排序的工作将分散在所有条目上。
如果数据来自电子来源,如文件,最好将其全部读取,然后进行排序。
无论您选择如何处理它,请将其存储在 std::vector
或std::deque
,因为它们可以有效地利用具有良好缓存行为和高效随机访问的内存。
std::istream
"收集数据" - 具体来说,如果您需要标准输入(默认为键盘,或者某些重定向/管道文件或命令输出),则可以std::cin
,否则std::ifstream
直接读取文件。 例如:
double my_double;
if (!(std::cin >> my_double))
{
std::cerr << "unable to read and parse a double from standard inputn";
exit(1);
}
...use my_double...
用于存储值...最好从std::vector<double>
开始:
std::vector<double> my_doubles;
my_doubles.push_back(my_double);
// add all the doubles...
double total = 0;
for (auto& d : my_doubles)
total += d;
有关组合这些内容的示例:
// read/store all the numbers from the current position in the input stream...
while (std::cin >> my_double)
my_doubles.push_back(my_double);
如果有用,您可以对容器进行排序:
std::sort(std::begin(my_doubles), std::end(my_doubles)); // default increasing
std::sort(std::begin(my_doubles), std::end(my_doubles), // decreasing
[](double x, double y) { return x > y; });
使用其他容器类型,某些操作可能更容易,例如 - std::set<>
是在拒绝重复值的同时保持值排序的便捷方法,而std::multiset
可以存储重复项。
使用 Boost.Accumulators 框架。
这是他们的起始示例:
#include <iostream>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/moment.hpp>
using namespace boost::accumulators;
int main()
{
// Define an accumulator set for calculating the mean and the
// 2nd moment ...
accumulator_set<double, stats<tag::mean, tag::moment<2> > > acc;
// push in some data ...
acc(1.2);
acc(2.3);
acc(3.4);
acc(4.5);
// Display the results ...
std::cout << "Mean: " << mean(acc) << std::endl;
std::cout << "Moment: " << accumulators::moment<2>(acc) << std::endl;
return 0;
}
该框架定义了大量的累加器,通常提供所需统计操作的惰性和急切版本。如您所料,它也是可扩展的。