2013-11-19 3 views
1

Вечером все, у меня есть задание проблемы, которое просит написать программу, которая читает в кучке чисел из файла, и выводит оценки, среднее и стандартное отклонение букв. Письменные оценки и средний уровень, о котором я позаботился, но у меня проблемы со стандартным отклонением. Проблема в том, что моя программа читает во всех значениях и вычисляет среднее значение после этого. Поскольку формула для стандартного отклонения требует использования конкретной точки данных И среднего, ну, я просто не уверен, как это сделать. Одна из моих идей заключалась в том, чтобы попытаться открыть программу дважды, так что во втором прогоне (по какой точке она вычисляется среднее значение) она может рассчитать стандартное отклонение. Однако компилятору это совсем не нравится. Любой совет?Поиск среднего и стандартного отклонения от числа, считанного из файла

#include "stdafx.h" 
#include <iostream> 
#include <fstream> 
#include <cmath> 
using namespace std; 

int main(){ 
ifstream file("grades.txt"); 
double number,sum=0,noNumbers=0,average=0; 
int noAs=0, noBs=0, noCs=0, noDs=0, noFs=0, noAms=0, noBms=0, noCms=0, noDms=0, noAps=0, noBps=0, noCps=0, noDps=0, quant=0, quanttot=0; 

while(file >> number){ 
    if(number >= 97 && number <=100){ 
    noAps++; 
    } 
    if(number >= 93 && number < 97){ 
    noAs++; 
    } 
    if(number >= 90 && number < 93){ 
    noAms++; 
    } 
if(number >= 87 && number <90){ 
    noBps++; 
    } 
    if(number >= 83 && number < 87){ 
    noBs++; 
    } 
    if(number >= 80 && number < 83){ 
    noBms++; 
    } 
    if(number >= 77 && number < 80){ 
    noCps++; 
    } 
    if(number >= 73 && number < 77){ 
    noCs++; 
    } 
    if(number >= 70 && number < 73){ 
    noCms++; 
    } 
    if(number >= 67 && number < 70){ 
    noDps++; 
    } 
    if(number >= 63 && number < 67){ 
    noDs++; 
    } 
    if(number >= 60 && number < 63){ 
    noDms++; 
    } 
    if(number < 60){ 
    noFs++; 
    } 
    noNumbers++; 
    sum = sum += number; 
} 
average = sum/noNumbers; 
while(file >> number){ 
    quant = (number - average)*(number-average); 
    quanttot = quanttot + quant; 
} 
double sigma; 
sigma = sqrt(quanttot/noNumbers); 
cout << "Average is: " << average << endl; 
cout << "Standard deviation is: " << sigma << endl; 
ofstream newfile("grades2.txt"); 
newfile << "A+'s: " << noAps << endl 
    << "A's: " << noAs << endl 
    <<"A-'s: " << noAms << endl 
    <<"B+'s: " << noBps << endl 
    << "B's: " << noBs << endl 
    << "B-'s: " << noBms << endl 
    <<"C+'s: " << noCps << endl 
    <<"C's: " << noCs << endl 
    <<"C-'s: " << noCms << endl 
    <<"D+'s: " << noDps << endl 
    <<"D's: " << noDs << endl 
    << "D-'s: " << noDms << endl 
    << "F's: " << noFs << endl; 
newfile.close(); 
cout << "Press any key to continue...THEN PRESS ENTER!\n:"; 
int f; 
cin >> f; 
return 0; 

}


Ах, сохраняя число в массив, чтобы манипулировать позже была хорошая идея, на самом деле. Поэтому я изменил код так:

#include "stdafx.h" 
#include <iostream> 
#include <fstream> 
#include <cmath> 
using namespace std; 

int main(){ 
ifstream file("grades.txt"); 
double sum=0,noNumbers=0,average=0; 
int noAs=0, noBs=0, noCs=0, noDs=0, noFs=0, noAms=0, noBms=0, noCms=0, noDms=0, noAps=0, noBps=0, noCps=0, noDps=0, quant=0, quanttot=0; 
int i = 1; 
double number[500]; 
while(file >> number[i]){ 
while(number[i]<=100){ 

    if(number[i] >= 97 && number[i] <=100){ 
    noAps++; 
    } 
    if(number[i] >= 93 && number[i] < 97){ 
    noAs++; 
    } 
    if(number[i] >= 90 && number[i] < 93){ 
    noAms++; 
    } 
    if(number[i] >= 87 && number[i] < 90){ 
    noBps++; 
    } 
    if(number[i] >= 83 && number[i] < 87){ 
    noBs++; 
    } 
    if(number[i] >= 80 && number[i] < 83){ 
    noBms++; 
    } 
    if(number[i] >= 77 && number[i] < 80){ 
    noCps++; 
    } 
    if(number[i] >= 73 && number[i] < 77){ 
    noCs++; 
    } 
    if(number[i] >= 70 && number[i] < 73){ 
    noCms++; 
    } 
    if(number[i] >= 67 && number[i] < 70){ 
    noDps++; 
    } 
    if(number[i] >= 63 && number[i] < 67){ 
    noDs++; 
    } 
    if(number[i] >= 60 && number[i] < 63){ 
    noDms++; 
    } 
    if(number[i] < 60){ 
    noFs++; 
    } 
    noNumbers++; 
    i++; 
} 
} 
for(int i=0; i = noNumbers; i++){ 
    sum = sum + number[i]; 
} 
average = sum/noNumbers; 

for(int i=0; i=noNumbers;i++){ 
    quant = (number[i] - average)*(number[i] - average); 
    quanttot = quanttot + quant; 
} 

double sigma; 
sigma = sqrt(quanttot/noNumbers); 
cout << "Average is: " << average << endl; 
cout << "Standard deviation is: " << sigma << endl; 
ofstream newfile("grades2.txt"); 
newfile << "A+'s: " << noAps << endl 
    << "A's: " << noAs << endl 
    <<"A-'s: " << noAms << endl 
    <<"B+'s: " << noBps << endl 
    << "B's: " << noBs << endl 
    << "B-'s: " << noBms << endl 
    <<"C+'s: " << noCps << endl 
    <<"C's: " << noCs << endl 
    <<"C-'s: " << noCms << endl 
    <<"D+'s: " << noDps << endl 
    <<"D's: " << noDs << endl 
    << "D-'s: " << noDms << endl 
    << "F's: " << noFs << endl 
    << "Average: " << average << endl 
    << "Standard Deviation: " << sigma << endl; 
newfile.close(); 
cout << "Press any key to continue...THEN PRESS ENTER!\n:"; 
int f; 
cin >> f; 
return 0; 

}

Однако, теперь я получаю безумную ошибку, которая заставляет перерыв и берет меня в какой-то MumboJumbo кода в компиляторе. Кто-нибудь видит какие-либо ошибки, которые могут вызвать это? Чтобы быть конкретным, ошибка, которую он дает мне, находится во всплывающем окне и говорит: «Необработанное исключение в 0x5A221D7F (msvcp110d.dll) в ConsoleApplication79.exe: 0xC0000005: место чтения нарушения доступа 0x4050C000». Кроме того, в текстовом файле есть где-то от 300 до 450 номеров, поэтому у массива не должно быть пробелов.

+0

Кроме того, если кто-то нуждается в уточнении для расчета стандартного отклонения: http://www.mathsisfun.com/data/standard-deviation-formulas.html –

+1

Просьба уточнить, «компилятор не нравится». Если вы попытаетесь дважды открыть файл в своем коде, программа не компилируется по какой-либо причине? Кроме того, идеальным подходом было бы динамически распределенное пространство для новых номеров (т. Е. Один связанный список), чтобы сохранить все значение, считанное из файла, а затем выполнить вычисления с использованием списка и, наконец, очистить назначенную ему память , – DevNull

+0

'sum = sum + = number;' Может быть либо 'sum + = number', либо' sum = sum + number'. Но не сочетайте их. – hankd

ответ

3

Если вы используете C++, подумайте о том, чтобы положить ваши номера в vector.

Как только у вас есть вектор, довольно легко написать функции, которые перебирают элементы в векторе. Ваши функции могут вычислять все виды статистики: среднее (среднее), стандартное отклонение, медианное и т. Д. Или вы можете использовать библиотеки, такие как Boost, чтобы сделать это за вас.

Нет необходимости читать файл дважды, если только вы не имеете дело с миллионами чисел, или ваша машина каким-то образом ограничена для памяти, что, по-видимому, не имеет места здесь. Сохраните номера, с которыми работаете, в стандартный контейнер C++ (вектор) и узнайте, как работать с содержимым этого контейнера, чтобы получить нужные ответы.

0

Я бы посоветовал вам прочитать файл в массив или вектор (если файл слишком велик). Кроме того, чтобы избежать возможных ошибок округления, сделать ваш текущий общий переменное (double noNumbers) целого типа, а не тип с плавающей точкой (см это Is using increment (operator++) on floats bad style?)

Если файл достаточно мал, если вы читаете в массив можно выполнять любой численные вычисления, которые вы хотите без неэффективного повторного чтения содержимого файла

0

Существует способ расчета std. отклонение за один проход; лучше, если вы это выясните.

0

Не нужно ничего хранить в векторе или в другом месте. Все эти статистические данные могут быть рассчитаны за один проход, путем обновления по мере ввода каждого нового поплавка. Фактически вы просматриваете данные 3 раза выше. Избавьтесь от вектора и попробуйте выполнить все вычисления при чтении данных.

Смежные вопросы