Rückgabe von Wechselgeld nach einem Kauf
-
Geht sicher auch wesentlich eleganter und wiederverwendbarer, aber damit du siehst, wie ich es meine, reichts, denk ich.
#include <iostream> #include <vector> using namespace std; int main() { int kaufbetrag, gezahlt; cout << "Bitte geben Sie den den Kaufbetrag in Cent ein: " << endl; cin >> kaufbetrag; cout << "Bitte geben Sie den Gezahlten Betrag in Cent ein: " << endl; cin >> gezahlt; int wechselgeld( gezahlt - kaufbetrag ); if ( wechselgeld < 0 ) { cout << "zu wenig, cu" << endl; return 1; } if ( wechselgeld == 0 ) { cout << "passt, cu" << endl; return 0; } vector <int> geldEinheiten; geldEinheiten.reserve( 15 ); geldEinheiten.push_back( 50000 ); geldEinheiten.push_back( 20000 ); geldEinheiten.push_back( 10000 ); geldEinheiten.push_back( 5000 ); geldEinheiten.push_back( 2000 ); geldEinheiten.push_back( 1000 ); geldEinheiten.push_back( 500 ); geldEinheiten.push_back( 200 ); geldEinheiten.push_back( 100 ); geldEinheiten.push_back( 50 ); geldEinheiten.push_back( 20 ); geldEinheiten.push_back( 10 ); geldEinheiten.push_back( 5 ); geldEinheiten.push_back( 2 ); geldEinheiten.push_back( 1 ); cout << "Im Wechselgeld sind:" << endl; for ( vector <int>::const_iterator it( geldEinheiten.begin() ); it != geldEinheiten.end(); ++it ) { int anzahl( 0 ); while ( *it <= wechselgeld ) { ++anzahl; wechselgeld -= *it; } cout << anzahl << " Gegenstaende, die einen Wert von " << *it << " Cent repräsentieren." << endl; } return 0; }
-
Hast du auch einen Tipp wie ich das mit einem Array mache? Ich bekomme es nicht hin...
-
Klar kannst du dort oben den vector<> durch ein Array und die Iteratoren durch Index-Zugriffe ersetzen. Aber die STL-Containerklassen sind wesentlich flexibler als nackte Arrays, also solltest du sie auch nutzen
-
Clonex schrieb:
Hast du auch einen Tipp wie ich das mit einem Array mache? Ich bekomme es nicht hin...
Normalerweise fass ich ekelwutzige Arrays nur an wenn es sich gar nicht vermeiden lässt, weil der code dadurch (wie du gleich sehen wirst) automatisch und unvermeidlich komisch wird, aber weil du es bist.
#include <iostream> #include <math.h> using namespace std; #define AbGehtDiePost for ( int n( 14 ); n >= 0; --n ) int main() { int kaufbetrag, gezahlt; cout << "Bitte geben Sie den den Kaufbetrag in Cent ein: " << endl; cin >> kaufbetrag; cout << "Bitte geben Sie den Gezahlten Betrag in Cent ein: " << endl; cin >> gezahlt; int wechselgeld( gezahlt - kaufbetrag ); if ( wechselgeld < 0 ) { cout << "zu wenig, cu" << endl; return 1; } if ( wechselgeld == 0 ) { cout << "passt, cu" << endl; return 0; } int geldEinheiten[15]; // boeses Array AbGehtDiePost { geldEinheiten[n] = (pow((n%3),2) + 1)*pow(10,floor(n/3)); } cout << "Im Wechselgeld sind:" << endl; AbGehtDiePost { int anzahl( 0 ); while ( *(geldEinheiten+n) <= wechselgeld ) { ++anzahl; wechselgeld -= *(geldEinheiten+n); } cout << anzahl << " Gegenstaende, die einen Wert von " << *(geldEinheiten+n) << " Cent repräsentieren." << endl; } return 0; }
-
Dobi schrieb:
Clonex schrieb:
Hast du auch einen Tipp wie ich das mit einem Array mache? Ich bekomme es nicht hin...
Normalerweise fass ich ekelwutzige Arrays nur an wenn es sich gar nicht vermeiden lässt, weil der code dadurch (wie du gleich sehen wirst) automatisch und unvermeidlich komisch wird, aber weil du es bist.
Selten so einen dummen Scheiß gelesen.
Sollen das Makro da und die Formel Erziehungsversuche sein?
Sei doch so fair und übersetze dein vector-Programm einigermaßen unverfälscht in ein Array-Programm.
So zum Beispiel:#include <iostream> #include <vector> using namespace std; template<typename T,size_t size> T* begin(T (&arr)[size]) { return &arr[0]; } template<typename T,size_t size> T* end(T (&arr)[size]) { return &arr[size]; } int main() { int kaufbetrag, gezahlt; cout << "Bitte geben Sie den den Kaufbetrag in Cent ein: " << endl; cin >> kaufbetrag; cout << "Bitte geben Sie den Gezahlten Betrag in Cent ein: " << endl; cin >> gezahlt; int wechselgeld( gezahlt - kaufbetrag ); if ( wechselgeld < 0 ) { cout << "zu wenig, cu" << endl; return 1; } if ( wechselgeld == 0 ) { cout << "passt, cu" << endl; return 0; } int geldEinheiten[15]={ 50000,20000,10000, 5000,2000,1000, 500,200,100, 50,20,10, 5,2,1, }; cout << "Im Wechselgeld sind:" << endl; for ( int* it(begin(geldEinheiten)); it != end(geldEinheiten); ++it ) { int anzahl( 0 ); while ( *it <= wechselgeld ) { ++anzahl; wechselgeld -= *it; } cout << anzahl << " Gegenstaende, die einen Wert von " << *it << " Cent repräsentieren." << endl; } return 0; }
Und, welches ist hübscher?
-
volkard schrieb:
Und, welches ist hübscher?
Dann musst du aber fairerweise jetzt auch ein von dir geschriebenes STL-Containerprogramm dagegen setzen, bei dem du dir die gleiche Mühe gibst. Vorzugsweise mit C++0x-Initialisierungslisten.
-
volkard schrieb:
Selten so einen dummen Scheiß gelesen.
Sollen das Makro da und die Formel Erziehungsversuche sein?
Sei doch so fair und übersetze dein vector-Programm einigermaßen unverfälscht in ein Array-Programm.Sollte eigentlich nur Spaß sein, gute Güte. :p
volkard schrieb:
Und, welches ist hübscher?
Natürlich deins, was für ne Frage.
Edit: Da der Zwinkersmiley im Post vorhin nicht gereicht hat, versuch ich, durch etwas mehr Persönlichkeit zu versöhnen.
http://i54.tinypic.com/29zrn6v.jpg
PS: Serotonin! Es sonnt doch.
-
Darf ich auch meckern?
Ich finde direct initialization da, wo copy initialization gereicht hätte, hässlich. Mir läuft da immer ein Schauer über den Rücken, wenn ich so etwas lese.
int i( 14 ); // direct initialization int j = 15; // copy initialization
Lasst Euch von den Namen doch nicht durcheinander bringen. DI ist jetzt nicht "schneller", weil's "direct" ist. Da kommt bei (wahrscheinlich) allen Compiler eh der gleiche Code bei raus.
Ein statisches, konstantes Array hier als Lookup-Tabelle ist jetzt auch keine ganz so schlechte Idee.
Bzgl Minimale Anzahl von Münzen/Scheinen, fällt mir noch Backtracking ein. Aber das ist bei diesen Münz/Schein-Werten überflüssig. Bei anderen "komischen" Münzwerten müsste man dann die Lösung anders finden. Beispiel:
Münzen im Wert von 50, 40, 30, 5 Cent. Betrag: 70 Cent
70 = 50 + 5 + 5 + 5 + 5 (ist aber offensichtlich nicht optimal!)
70 = 40 + 30 (optimal)
-
krümelkacker schrieb:
Darf ich auch meckern?
Ich finde direct initialization da, wo copy initialization gereicht hätte, hässlich. Mir läuft da immer ein Schauer über den Rücken, wenn ich so etwas lese.
int i( 14 ); // direct initialization int j = 15; // copy initialization
Lasst Euch von den Namen doch nicht durcheinander bringen. DI ist jetzt nicht "schneller", weil's "direct" ist. Da kommt bei (wahrscheinlich) allen Compiler eh der gleiche Code bei raus.
Klar darfste meckern.
Dass bei Zuweisung an einer Deklaration nicht der Zuweisungsoperator benutzt wird, weiß ich. Ich find "int i( 14 );" aber irgendwie intuitiver als "int i = 14;", weil man dann diesen "Tweak" in der Sprache gar nicht bedenken muss.
-
Dobi schrieb:
krümelkacker schrieb:
Darf ich auch meckern?
Ich finde direct initialization da, wo copy initialization gereicht hätte, hässlich. Mir läuft da immer ein Schauer über den Rücken, wenn ich so etwas lese.
int i( 14 ); // direct initialization int j = 15; // copy initialization
Lasst Euch von den Namen doch nicht durcheinander bringen. DI ist jetzt nicht "schneller", weil's "direct" ist. Da kommt bei (wahrscheinlich) allen Compiler eh der gleiche Code bei raus.
Klar darfste meckern.
Dass bei Zuweisung an einer Deklaration nicht der Zuweisungsoperator benutzt wird, weiß ich. Ich find "int i( 14 );" aber irgendwie intuitiver als "int i = 14;", weil man dann diesen "Tweak" in der Sprache gar nicht bedenken muss.Ob da der Zuweisungsoperator genutzt wird oder nicht, ist hier gar nicht die Frage, das sollte ja wohl klar sein, da es eine Initialisierung ist und keine Zuweisung. Es ging um Direct-Initialization oder Copy-Initialization
Lg freeG
Lg freeG
-
fr33g schrieb:
Ob da der Zuweisungsoperator genutzt wird oder nicht, ist hier gar nicht die Frage, das sollte ja wohl klar sein, da es eine Initialisierung ist und keine Zuweisung. Es ging um Direct-Initialization oder Copy-Initialization
Weiß er ja, hat er ja auch geschrieben dass er das weiß.
Ob so oder so ist Jacke wie Hose. Es macht das selbe, und ob es jetzt ein "tweak" in der Sprache ist oder nicht, ist auch wurscht, weils beides gängige Praxis ist. Man sollte beides lesen können ohne drüber zu stolpern. Es ist eine reine Geschmacksfrage, welche Form man vorzieht.
-
pumuckl schrieb:
fr33g schrieb:
Ob da der Zuweisungsoperator genutzt wird oder nicht, ist hier gar nicht die Frage, das sollte ja wohl klar sein, da es eine Initialisierung ist und keine Zuweisung. Es ging um Direct-Initialization oder Copy-Initialization
Weiß er ja, hat er ja auch geschrieben dass er das weiß.
Ob so oder so ist Jacke wie Hose. Es macht das selbe, und ob es jetzt ein "tweak" in der Sprache ist oder nicht, ist auch wurscht, weils beides gängige Praxis ist. Man sollte beides lesen können ohne drüber zu stolpern. Es ist eine reine Geschmacksfrage, welche Form man vorzieht.Ich weiß ja dass er das weiß. Aber krümelkacker meinte ja den Unterschied zwischen Copy-Initialization und Direct-Initialization, den es oft gar nicht gibt. Und ich habe es dann so verstanden, als wie Dobi das gar nicht gemerkt hat, sondern dachte, Krümelkacker meinte das mit dem Zuweisungsoperator. Aber darum ging es ja Krümelkacker nicht.
Aber is ja jetzt auch WurschtLg freeG
-
Nee, ist ne reine Geschmacksfrage (in den meisten Fällen). Meine Präferenz habe ich kund getan (CI). Für mich sieht DI zu sehr nach einer Funktionsdeklaration aus. In C schreibt das ja auch keiner so auf.
Ich wollte nur nicht, dass einer denkt, dass DI irgendwie effizienter sei als CI und es nur deswegen verwendet.
-
Dobi schrieb:
Geht sicher auch wesentlich eleganter und wiederverwendbarer, aber damit du siehst, wie ich es meine, reichts, denk ich.
#include <iostream> #include <vector> using namespace std; int main() { ... for ( vector <int>::const_iterator it( geldEinheiten.begin() ); it != geldEinheiten.end(); ++it ) { int anzahl( 0 ); while ( *it <= wechselgeld ) { ++anzahl; wechselgeld -= *it; } cout << anzahl << " Gegenstaende, die einen Wert von " << *it << " Cent repräsentieren." << endl; } return 0; }
Fehlt nur noch der Korrektheitsbeweis. Wenn man z.B. auch 4€ Münzen hätte, wäre deine Strategie ja fehlerhaft (z.B. 8€ mittels 5€+2€+1€ zu wechseln wäre dann nicht optimal, sondern 4€+4€). Warum klappt die Strategie also in diesem Fall?
-
life schrieb:
Warum klappt die Strategie also in diesem Fall?
Weil die nächstgrößere Einheit bei unserer Währung immer mindestens doppelt so groß ist wie die kleinere.
Hab ich deinen Test bestanden?
-
Dobi schrieb:
life schrieb:
Warum klappt die Strategie also in diesem Fall?
Weil die nächstgrößere Einheit bei unserer Währung immer mindestens doppelt so groß ist wie die kleinere.
Hab ich deinen Test bestanden?Gegenbeispiel:
Die 1-Cent-Münze wurde abgeschafft.
Will 8 Cent rausgeben.
Gebe zuerst 5 und verzweifle.
-
Mhh, stimmmt. Ok, dann vielleicht, weil geldEinheiten.at(n) immer größer als geldEinheiten.at(n+1)*2 ist und weil es die Basiseinheit auch als Element gibt?
Was machen wir eigentlich, wenn wir beliebige Geldeinheiten haben, von allen aber nicht beliebig viel. Dann kanns ja sein, dass das Ziel ist, dem Kunden möglichst viel Wechselgeld zurückzugeben aber nicht mehr als nötig. Hilft es dann, wenn wir uns vorstellen, dass der Kunde das Welchselgeld nicht in ein Portemonnaie tut, sondern in einen Rücksack?
-
Dobi schrieb:
Mhh, stimmmt. Ok, dann vielleicht, weil geldEinheiten.at(n) immer größer als geldEinheiten.at(n+1)*2 ist und weil es die Basiseinheit auch als Element gibt?
Gegenbeispiel:
90€ Schein
25€ Schein
1€ Münze
Will 100€ rausgeben.
Gebe zuerst 90€ und verzweifle.
-
life schrieb:
Dobi schrieb:
Mhh, stimmmt. Ok, dann vielleicht, weil geldEinheiten.at(n) immer größer als geldEinheiten.at(n+1)*2 ist und weil es die Basiseinheit auch als Element gibt?
Gegenbeispiel:
90€ Schein
25€ Schein
1€ Münze
Will 100€ rausgeben.
Gebe zuerst 90€ und verzweifle.90+1+1+1+1+1+1+1+1+1+1 ist zwar unschön, aber nicht zum Verzweifeln.
-
Dobi schrieb:
life schrieb:
Dobi schrieb:
Mhh, stimmmt. Ok, dann vielleicht, weil geldEinheiten.at(n) immer größer als geldEinheiten.at(n+1)*2 ist und weil es die Basiseinheit auch als Element gibt?
Gegenbeispiel:
90€ Schein
25€ Schein
1€ Münze
Will 100€ rausgeben.
Gebe zuerst 90€ und verzweifle.90+1+1+1+1+1+1+1+1+1+1 ist zwar unschön, aber nicht zum Verzweifeln.
Jedenfalls nicht optimal.