查找从文件中读取的数字的平均值和标准差

时间:2013-11-19 23:21:01

标签: c++ readfile

晚上所有,我有一个问题分配,要求编写一个程序,从文件中读取一堆数字,并输出字母等级,平均值和标准差。字母等级和平均值我已经处理过了,但我在标准偏差方面遇到了麻烦。问题是我的程序读入所有值并在完成后计算平均值。由于标准差的公式需要使用特定的数据点和平均值,所以,我只是不确定如何去做。我的一个想法是尝试让程序打开文件两次,以便在第二次运行时(此时它具有平均值计算)它可以计算标准偏差。但是,编译器完全不喜欢这个。有什么建议吗?

#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代码。有没有人看到任何可能导致此错误的错误?具体来说,它给出的错误是在一个弹出窗口中说:“ConsoleApplication79.exe中0x5A221D7F(msvcp110d.dll)的未处理异常:0xC0000005:访问冲突读取位置0x4050C000。”此外,文本文件中有大约300到450个数字,因此数组不应该用尽插槽。

4 个答案:

答案 0 :(得分:3)

如果您使用的是C ++,请考虑将您的号码放入vector

一旦有了向量,就可以很容易地编写迭代向量中元素的函数。您的函数可以计算所有类型的统计数据:平均值(平均值),标准差,中位数等。或者您可以使用Boost等库来为您执行此操作。

除非你正在处理数百万的数字或者你的机器在某种程度上限制了内存,否则实际上没有必要两次读取文件,这在这里似乎并非如此。将您正在使用的数字存储到标准C ++容器(向量)中,并学习如何使用该容器的内容来获得所需的答案。

答案 1 :(得分:0)

我建议您将文件读入数组或向量(除非文件太大)。另外,为避免潜在的舍入错误,请设置运行总变量(double noNumbers)  整数类型而不是浮点类型(请参阅此Is using increment (operator++) on floats bad style?

如果你读入数组文件足够小,你可以执行你想要的任何数值计算,而不会低效重读文件内容

答案 2 :(得分:0)

有一种计算标准的方法。一次通过的偏差;如果你搞清楚它会更好。

答案 3 :(得分:0)

无需在矢量或其他内容中存储任何内容。所有这些统计数据都可以在一次通过中计算,通过在每次新浮点数进入时进行更新。您实际上是在上面传递数据3次。摆脱向量,并尝试在读取数据时进行所有计算。