С.И.Хашин
Класс совсем простой, поэтому cpp-файл отсутствует, все лежит в dispers.h:
class dispers { public: double sum, sum2; int cnt; // constructors/destructor dispers(void) {sum=sum2=cnt=0;} void add(double v) { sum+=v; sum2+=v*v; cnt++;} void clear(void) {sum=sum2=cnt=0;} double mid(void) { return cnt==0? 0 : sum/cnt; } double off(void) { return cnt==0? 0 : sqrt(sum2/cnt - dSquare(sum/cnt)); } };
Допустим, что у нас имеется некоторый набор чисел:
x[0], x[1], ..., x[N-1].
Будем считать, что N велико, например, несколько миллиардов и числа читаются из файла последовательно.
Для нахождения mid среднего этих чисел, их не обязательно запоминать все, достаточно хранить только сумму прочитанных чисел sum и их количество cnt. Тогда в любой момент мы можем сказать, что среднее прочитанных чисел равно mid = sum/cnt.
А как узнать среднеквадратичное отклонение чисел x[i] от среднего?
Можно прочитать файл два раза, после первого прохода найти среднее значение mid, а после второго среднее отклонение от mid.
Но тоже самое можно сделать за один проход:
dispers di; for( int i=0; i<N; i++ ) di.add(x[i]); printf(" mid = %f\n", di.mid()); printf(" mid offset = %f\n", di.off());