Standardabweichung wird nicht korrekt berechnet wenn ich Noten nicht direkt im Konstruktor berechne



  • Hallo,

    ich bin in C++ noch ziemlicher Anfänger und habe in einem Programm im Nachhinein einen Unterschied festgestellt, den ich mir auf Anhieb nicht erklären kann. Mein Programm funktioniert nur dann korrekt, wenn ich die Noten direkt im Konstruktor vergebe oder wie in meinem Programm aus dem Konstruktor die Methode für die Notenberechnung aufrufe (Zeile 21). Rufe ich dagegen seperat aus der Mainmethode über eine Schleife die benoten() Methode auf (Zeile 175) wird alles richtig berechnet bis zur Standardabweichung und für diese kommt immer der Mittelwert heraus, es wird dann in Zeile 124 scheinbar immer nur 0 für studi.note eingesetzt. Aktiviere ich Zeile 21 und lösche Zeile 175 kommt auch eine korrekte Standardabweichung heraus.
    Ich frage mich an welcher Stelle da genau der Fehler passiert und warum?
    Wäre schön wenn mir jemand die Ursache erklären könnte. Danke schon Mal.

    PS: Die Funktionen zwischen den Structs und der main-Methode habe ich nur der Vollständigkeit mit eingefügt, diese funktionieren perfekt, es sollte erst eine Datei mit Klausurergebnissen selbst erzeugt und diese dann wieder eingelesen und als Structobjekte Studi angelegt und gespeichert werden. Aus den Punkten soll dann jeweils eine Note vergeben und dann die Teilnehmer mit Punktzahl und Note ausgegeben werden. Dann soll im 2. Struct Histogramm eine kleine Statistik berechnet und der Notenspiegel, der Mittelwert und die Standardabweichung ausgegeben werden.

    #include <iostream>
    #include <fstream>
    #include <time.h>
    #include <stdlib.h>
    #include <vector>
    #include <string>
    #include <stdio.h>
    #include <math.h>
    
    static unsigned int const TEILNEHMERZAHL = 100;
    
    struct Studi {
    
        int id;
        int a1, a2, a3, a4;
        int gesamtpunkte;
        double note;
    
        Studi(int id, int a, int b, int c, int d): id(id), a1(a), a2(b), a3(c), a4(d), gesamtpunkte(a+b+c+d)
        {
            //this->benote();
        }
    
        void benote()
        {
            if(gesamtpunkte >= 90)
                this->note = 1.0;
            else if(gesamtpunkte >= 80 && gesamtpunkte < 90)
                this->note = 1.3;
            else if(gesamtpunkte >= 70 && gesamtpunkte < 80)
                this->note = 1.7;
            else if(gesamtpunkte >= 60 && gesamtpunkte < 70)
                this->note = 2.0;
            else if(gesamtpunkte >= 50 && gesamtpunkte < 60)
                this->note = 2.3;
            else if(gesamtpunkte >= 40 && gesamtpunkte < 50)
                this->note = 2.7;
            else if(gesamtpunkte >= 30 && gesamtpunkte < 40)
                this->note = 3.0;
            else if(gesamtpunkte >= 20 && gesamtpunkte < 30)
                this->note = 3.3;
            else if(gesamtpunkte >= 10 && gesamtpunkte < 20)
                this->note = 3.7;
            else
                this->note = 4.0;
        }
    
        void print() const
        {
            printf("Id: %i\t%s %i\t%s %.1f\n", id, "Punkte:", gesamtpunkte, " Note:", note);
        }
    };
    
    
    struct Histogram
    {
        int count[10] = {0};        // alle 10 Stellen automatisch mit 0 initialisiert
        double average;
        double standardDeviation;
    
        void counter(double note){
    
            int zensur = static_cast<int> (10*note);    // in Int gecastet zum Vergleich
            switch(zensur)
            {
                case 10:
                    count[0]++;
                    break;
                case 13:
                    count[1]++;
                    break;
                case 17:
                    count[2]++;
                    break;
                case 20:
                    count[3]++;
                    break;
                case 23:
                    count[4]++;
                    break;
                case 27:
                    count[5]++;
                    break;
                case 30:
                    count[6]++;
                    break;
                case 33:
                    count[7]++;
                    break;
                case 37:
                    count[8]++;
                    break;
                default:
                    count[9]++;
            }
        }
    
        void notenspiegel()
        {
            std::cout << std::endl;
            std::cout << "Notenspiegel:"  << std::endl;
            std::cout << "Die Note 1.0 gab es: " << count[0] << " mal." << std::endl;
            std::cout << "Die Note 1.3 gab es: " << count[1] << " mal." << std::endl;
            std::cout << "Die Note 1.7 gab es: " << count[2] << " mal." << std::endl;
            std::cout << "Die Note 2.0 gab es: " << count[3] << " mal." << std::endl;
            std::cout << "Die Note 2.3 gab es: " << count[4] << " mal." << std::endl;
            std::cout << "Die Note 2.7 gab es: " << count[5] << " mal." << std::endl;
            std::cout << "Die Note 3.0 gab es: " << count[6] << " mal." << std::endl;
            std::cout << "Die Note 3.3 gab es: " << count[7] << " mal." << std::endl;
            std::cout << "Die Note 3.7 gab es: " << count[8] << " mal." << std::endl;
            std::cout << "Die Note 4.0 gab es: " << count[9] << " mal." << std::endl;
            std::cout << std::endl;
        }
    
        void calcAverage()
        {
            this->average = (count[0]+1.3*count[1]+1.7*count[2]+2.0*count[3]+2.3*count[4]+2.7*count[5]+3.0*count[6]+3.3*count[7]+3.7*count[8]+4.0*count[9])/TEILNEHMERZAHL;
        }
    
        void calcStandardDeviation(std::vector <Studi> &results)
        {
            double sum = 0;
            for(Studi studi: results){
                sum += pow(studi.note - average, 2);
            }
            double varianz = sum/TEILNEHMERZAHL;            // Varianz berechnen
            this->standardDeviation = sqrt(varianz);        // Standardabweichung berechnen
        }
    
    };
    
    void createData(){
    
        std::ofstream file;
        file.open("//home//agus//Schreibtisch//EiS//data.txt");
    
        file << TEILNEHMERZAHL << std::endl;
    
        srand(time(NULL));
    
        for(unsigned int id = 0; id < TEILNEHMERZAHL; ++id)
        {   // pro Student eine id und 4 Aufgaben mit 0-25 Punkten
            file << id << " " << rand() % 26 << " " << rand() % 26 << " " << rand() % 26 << " " << rand() % 26 << "\n\n";
        }
        file.close();
    }
    
    void readData(std::vector<Studi> &results){
    
        std::ifstream file;
        file.open("//home//agus//Schreibtisch//EiS//data.txt");
    
        unsigned int teilnehmerzahl;
        file >> teilnehmerzahl;
    
        int id, a1, a2, a3, a4;
        for(unsigned int i = 0; i < teilnehmerzahl; i++){
            file >> id >> a1 >> a2 >> a3 >> a4;
            Studi studi(id, a1, a2, a3, a4);
            results.push_back(studi);
        }
        file.close();
    }
    
    int main()
    {
        createData(); // Erzeugung der txt-Datei mit den Daten
        std::vector<Studi> results;  // Vektor vom Typ Studi um Studi-Objekte zu speichern
        readData(results);           // Einlesen der Ergebnisse
    
        Histogram histogram;
    
        /* Benotung, Zaehlung und Ausgabe der Ergebnisse */
        for(Studi teilnehmer: results){
            teilnehmer.benote();
            histogram.counter(teilnehmer.note);  // Note jedes Teilnehmers wird erfasst und mitgezaehlt
            teilnehmer.print();                  // Ausgabe der Noten
        }
    
        histogram.notenspiegel();                 // Ausgabe des Notenspiegels
    
        // Mittelwertberechnung
        histogram.calcAverage();
        printf("Der Mittelwert betraegt %.2f\n", histogram.average);
    
        // Berechnung der Standardabweichung
        histogram.calcStandardDeviation(results);
        printf("Die Standardabweichung betraegt %.2f\n", histogram.standardDeviation);
    
        return 0;
    }
    
    


  • for(Studi teilnehmer: results){ erzeugt jeweils eine Kopie. Benutze eine Referenz: for(Studi& teilnehmer: results){



  • Dankeschön, das hatte ich total übersehen.


Anmelden zum Antworten