Предположим, я хочу спросить у пользователя о некоторых целых числах, а затем я хочу сделать некоторые арифметические операции над ними (например, вычислить среднее значение, режим и т. Д.). Каков наилучший и наиболее эффективный способ сбора данных, чтобы иметь возможность применять к нему статистические функции?Лучший способ сохранить набор целых чисел
ответ
Медиана и режим намного проще найти по отсортированным данным.
Если пользователь будет вводить данные, то сортировка вставки в массив - отличный выбор, потому что работа сортировки будет распределена по всем элементам.
Если данные поступают из электронного источника, например файла, вероятно, лучше всего его прочитать, а затем отсортировать.
Независимо от того, как вы его решаете, сохраните его в 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 input\n";
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;
}
Каркас имеет plethora of accumulators определенную, часто обеспечивая как ленивых и нетерпеливых версии требуемых статистических операций. Как и следовало ожидать, он также расширяем.