Frage zu for-Schleife
-
wxSkip schrieb:
Mal ganz nebenbei, wieso nicht so:
#include <iostream> int main() { int result = 1; for(int i = 1; i<=10; i++) result = result / (1 / (double)i); cout << result; }Genau!
Und was haben wir algorithmisch gelernt?
-
So gehts auch:
// C99 #include <stdio.h> #include <math.h> int main() { printf("%.0f\n", exp(lgamma(11))); }Nur weiss ich leider nicht, wie die Gamma-Funktion in C++ heisst.

-
volkard schrieb:
wxSkip schrieb:
Mal ganz nebenbei, wieso nicht so:
#include <iostream> int main() { int result = 1; for(int i = 1; i<=10; i++) result = result / (1 / (double)i); cout << result; }Genau!
Und was haben wir algorithmisch gelernt?Dass a / ( 1 / x ) = a * x ist. Besser diese mathematische Erkenntnis, als gar keine Erkenntnis

-
volkard schrieb:
Michael E. schrieb:
Was habt ihr gegen die Aufgabenstellung? Es ist ein einfaches Problem, zu dem ein einfacher Algorithmus gefunden werden soll. Das find ich gut, um Programmieranfängern die nötige Denkweise näherzubringen.
Schreib mal einen englischen Text, ohne "a" oder "the" zu benutzen.
Kurz vorweg, das ist eine Aufgabe aus meinem Tutorial.
Die Idee dahinter ist:
Eine Aufgabe zu stellen deren Lösung ich selber leicht als richtig Beweisen kann. 1*2*3*4*... ist leicht nachzurechnen.
Zu diesem Zeitpunkt im Tutorial sind Funktionen aber noch unbekannt. Einfache zählschleifen wurden schon gemacht und dies sollte jetzt die komplexität erhöhen.Im Prinzip hätte ich auch 1 hoch 2 hoch 3 hoch 4... als Aufgabe geben können, da der Leser pow() nicht kennt, würde es auf das selbe hinauslaufen (multiplikationen). Aber da kommen so furchtbare zahlen raus...
Ich finde es aber auch nicht sonderlich gemein eine multiplikation zu verbieten. Denn der effekt ist, dass die Aufgabe mathematisch leicht überschaubar ist, aber dennoch praxisrelevant. Denn ersetze * durch eine komplexe Operation die du eben nicht direkt abbilden kannst, zB pow. Ein bisschen später kommt nämlich genau diese Aufgabe nochmal, nur dass man eigene funktion multiply() schreiben muss.
Ich finde diesen simplen Ansatz einfach besser - da ihn jeder verstehen kann. Dafür bekomme ich vermutlich keine Stilpunkte, aber die meisten Leute verstehen es trotzdem (und nur darum geht es mir).
-
Man könnte ja die Aufgabenstellung so für verschiedene Schwierigkeitsgrade erweitern:
1. Schreibe ein Programm, das 10! mit + berechnet (leicht)
2. Schreibe ein Programm, das 10! mit - berechnet (leicht)
3. Schreibe ein Programm, das 10! mit / berechnet (leicht)
4. Schreibe ein Programm, das 10! mit C-Funktionen berechnet (schwer)
5. Schreibe ein Programm, das 10! mit STL-Funktionen berechnet (schwer)Dann ist tricksen nämlich mal so gut wie ausgeschlossen
-
wxSkip schrieb:
5. Schreibe ein Programm, das 10! mit STL-Funktionen berechnet (schwer)
Oh, mit
std::multiplies()ist das aber auch nicht wahnsinnig schwer...
-
Nexus schrieb:
wxSkip schrieb:
5. Schreibe ein Programm, das 10! mit STL-Funktionen berechnet (schwer)
Oh, mit
std::multiplies()ist das aber auch nicht wahnsinnig schwer...
Nunja, wenn man noch nie was von STL gehört hat und noch nie eine Funktion verwendet hat... ^^
-
Okay, das stimmt, aber dann liegt der Schwerpunkt halt nicht mehr im Algorithmischen. Ansonsten (ich wollte wieder mal reine STL benutzen :)):
int filler() { static int i; return ++i; } int main() { std::vector<int> vec(5); std::generate(vec.begin(), vec.end(), &filler); int result = std::accumulate(vec.begin(), vec.end(), 1, std::multiplies<int>()); }
-
Shade Of Mine schrieb:
Dafür bekomme ich vermutlich keine Stilpunkte, aber die meisten Leute verstehen es trotzdem (und nur darum geht es mir).
Ich finde das gut so. Nachher führst du ja auch noch Funktionen ein, damit sieht das gleiche Programm fast genauso aus wie man es mit dem * schreiben würde. Da ist das Ergebnis dann schon ein alter Bekannter. Den kann man wieder besuchen, wenn man Rekursionen durchmacht und die unumgängliche Fakultät bringt. Ich finde das ist guter Stil.

-
wxSkip schrieb:
Dann ist tricksen nämlich mal so gut wie ausgeschlossen
Wobei ich natürlich kein Problem habe wenn man trickst.
volkards
std::cout << 3628800 << "\n";
ist zB eine korrekte Lösung. Man hat damit eine wichtige Lektion gelernt. Sofern man natürlich selber darauf gekommen ist. Zwar nicht die Lektion die man lernen hätte sollen, aber es ist ja kein Test wo ich mich als Tester profilieren will, sondern der Leser soll etwas lernen. Wenn er etwas lernt, dann ist das Ziel erreicht. Auch wenn er andere Sachen lernt als ich ursprünglich geplant hatte.zB könnte der Leser ja auch einen Code von mir sehen und sagen "nein, schlechtes Tutorial" auch damit hat er etwas gelernt - besser als wenn er sich stundenlang reinbeisst und nichts rauskommt.