Array mit Benutzereingegebenen länge erstellen



  • Nö, dabei kann es zu Rundungsfehlern kommen. Einfach aufsummieren und durch die Anzahl teilen.



  • Achso ja war ja auch totaler quatsch. Er redete ja von der Standardabweichung.

    Danke - Enomine



  • War doch ok. Eine Teilaufgabe war doch, den Mittelwert zu berechnen. Für die Standardabweichung brauchst du zusätzlich noch die Summe der Quadrate der Eingabe. Du musst nur drei Werte verwalten: Die Anzahl der Zahlen, die Summe der Zahlen und die Summe der Quadrate der Zahlen.



  • Ähm, so einfach geht das nicht. Du brauchst ja nicht die Quadrate, sondern die Quadrate der Abweichungen vom Mittel, also summe((x-xmean)^2).

    Für Online-Algorithmen siehe z.B. hier: https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Online_algorithm



  • SeppJ schrieb:

    Für Mittelwert und Standardabweichung brauchst du die Werte gar nicht zu speichern. Kannst du direkt on-the-fly berechnen. Mittelwert ist trivial, aber mit der Standardabweichung könntest du wahrscheinlich sogar deinen Lehrer zutiefst beeindrucken, wenn du darauf kommst. Der Lehrer, der solche Aufgaben stellt, hat nämlich bestimmt noch nie gesehen, ob und wie das geht.

    Folglich wäre es auch gar nicht nötig, die Anzahl der Werte im Voraus zu kennen. Der Benutzer soll einfach sagen, wenn er fertig ist. Aber wenn die dumme Aufgabenstellung das nun einmal verlangt... 😡

    Standardabweichung = Wurzel aus: (1/n * Summe für jede Zahl: (Die Zahl - Mittelwert aller Zahlen)²

    Oder eben die Definition selbst nachschlagen 😉

    Einsetzen (bsp n = 2):

    Wurzel aus: (1/n * ((z[1] - m)² + (z[2] - m)²))

    Binomische Formel auflösen:

    Wurzel aus: (1/n * (z[1]² - 2z[1]m + m² + z[2]² - 2z[2]m + m²))

    Umstellen:

    Wurzel aus: (1/n * ([z[1]² + z[2]²] + (2m²) + (2m[-z[1]-z[2]]))

    Für 1/n zähle ich die anzahl der eingebenen Zahlen mit.
    Für die erste eckicke Klammer verwende ich eine Variable, die die Quadrate aufsummiert.
    Für die 2m² kann ich n*Mittelsumme² rechnen.
    Für die Mittelsumme habe ich eine Variable, die die Zahlen aufaddiert und teile es durch n. Da das Quadrat höher bindet kann ich nicht gleich die aufsummierte Summe nehmen.
    Für die letzte Eckicke klammer kann ich das negative der aufsummierten Summe nehmen.

    So korrekt?

    Danke - Enomine



  • Kannste doch selbst prüfen. Einfach mit ein paar Zahlen ausprobieren und dann selbst nachrechnen.


  • Mod

    Enomine schrieb:

    So korrekt?

    Siehe wobs Link für Formeln, Herleitungen, Verbesserungsvorschläge (auf die man von selber wahrscheinlich nicht so schnell käme), und konkrete Implementierungen (zwar in Python, aber sollte sich leicht übertragen lassen).



  • Naja du hattest es so wie ein Rätsel aufgeschrieben, also wollte ich es auch selbst lösen.

    Folgendes, wie oben beschrieben, hat sich bei der Eingabe von 5 (Anzahl) und danach 3,4,5,6,7 als richtig erwiesen:

    // "Bung1.cpp": Definiert den Einstiegspunkt für die Konsolenanwendung.
    //
    
    #include "stdafx.h"
    #include <iostream>
    #include <string>
    
    int main()
    {
    	int anzahl;
    	std::cout << "Wie viele Zahlen moechtest du eingeben?";
    	std::cin >> anzahl;
    
    	float summe = 0;
    	float summeQuadrate = 0;
    
    	float totalAbweichung = 0;
    	float mittelwert;
    	float varianz;
    	float standardabweichung;
    
    	for (int i = 1; i <= anzahl; i++) {
    		std::cout << "Gib die " << i << "te Zahl an:";
    		float zahl;
    		std::cin >> zahl;
    		std::cout << "Eingegebene Zahl: " << zahl << std::endl;
    		summe += zahl;
    		summeQuadrate += zahl * zahl;
    		float mittelwert = summe / i;
    		float varianz = (1./i *(summeQuadrate + i*mittelwert*mittelwert - 2*mittelwert*summe));
    		float standardabweichung = sqrt(varianz);
    		std::cout << "Mittelwert: " << mittelwert << std::endl;
    		std::cout << "Varianz: " << varianz << std::endl;
    		std::cout << "Standardabweichung: " << standardabweichung << std::endl;
    	}
    
    	std::cout << "Danke für die Benutzung des Programms.";
    	std::cin >> anzahl;
        return 0;
    }
    

    Danke - Enomine



  • Berechne doch mal die Stddev von 10003, 10004, 10005, 10006, 10007. Die sollte ja genauso groß sein wie die von 3,4,5,6,7.

    Wenn du mutig bist, rechne auch noch mal die von 100001 und 100002 aus - nur 2 Zahlen, das geht im Kopf bestimmt besser als mit deinem Programm 😉



  • wob schrieb:

    Berechne doch mal die Stddev von 10003, 10004, 10005, 10006, 10007. Die sollte ja genauso groß sein wie die von 3,4,5,6,7.

    Wenn du mutig bist, rechne auch noch mal die von 100001 und 100002 aus - nur 2 Zahlen, das geht im Kopf bestimmt besser als mit deinem Programm 😉

    Also ohne es ausprobiert zu haben gehe ich mal davon aus, dass du mich auf einen integer-overflow hinweisen willst 😉

    Danke - Enomine



  • Ich meine float "overflow" 😉



  • Da du mit floats arbeitest, wird es wohl kaum einen Integer-Overflow geben. Nichtsdestoweniger kommen falsche Ergebnisse raus wegen fehlender Genauigkeit. Wenn du ein 2-Pass-Verfahren nimmst, also erst den Mittelwert berechnest, passiert die das bei diesen Zahlen nicht. Daher siehe auch noch mal meinen Link. Wichtig ist immer, dass dein Algorithmus auch numerisch stabil ist.


Anmelden zum Antworten