Fahrkartenautomat; Rückgeld mit möglichst großen Scheinen zurückgeben



  • Hallo Community, 😀

    ich bin relativ neu mit C++ und meine Aufgabe ist es, einen Fahrkartenautomat zu programmieren.

    Der Nutzer soll ein Ziel eingeben. Der Automat berechnet dann einen Preis je nach Entfernung der Haltestellen. Nun muss der Nutzer den Betrag für ein Ticket bezahlen, indem er einen Wert eingibt und der Automat berechnet das Rückgeld. Bis dahin alles kein Problem.

    Im Automaten sind die Scheine 100, 50, 20, 10, 5, 2, 1 alle jeweils 2 Mal enthalten. Ziel ist es dem Nutzer möglichst große Scheine wieder zurück zu geben.

    Beträgt z.B. das Rückgeld 95€, so soll der Automat 1x 50€, 2x 20€ und 1x 5€ ausgeben.

    Ich probiere seit Ewigkeiten an diesem Problem, komme aber leider nicht auf die richtige Lösung. Hat jemand eine Idee, wie ich das am besten umsetzen könnte?

    Ein großes Dankeschön an alle, die eine Idee haben! 🙂



  • @noaaah In diesem Forum suchen, dieselbe Frage hat hier vor nicht allzu langer Zeit hier einen riesigen Thread hervorgebracht.

    Edit: es war dieser hier: https://www.c-plusplus.net/forum/topic/350091/1-bis-100-centbeträge-möglichkeiten-kombinationen-algorithmus


  • Mod

    Stell bitte konkrete Fragen. Auf so etwas wie

    Hat jemand eine Idee, wie ich das am besten umsetzen könnte?

    bekommst du höchstens "Ja" oder "Nein" als Antwort. Niemand wird eine komplette Abhandlung darüber schreiben, was und wie man hier alles machen könnte, bloß damit sich am Ende heraus stellt, dass du eigentlich wissen wolltest, ob du lieber "5€" oder "€5" schreiben solltest...

    Siehe: https://www.c-plusplus.net/forum/topic/200753/du-brauchst-hilfe

    Außerdem: C++ ist nicht C++/CLI und auch nicht C und auch nicht C#. Das sind alles ganz unterschiedliche Sprachen, trotz ähnlicher Namen. Ich habe das Thema daher nach C++ verschoben.

    PS: Die Antwort auf deine Frage ist übrigens "Ja" 🙂



  • @noaaah sagte in Fahrkartenautomat; Rückgeld mit möglichst großen Scheinen zurückgeben:

    Hat jemand eine Idee, wie ich das am besten umsetzen könnte?

    Nimm dir (echtes oder Monopoly) Geld und mach das mal per Hand.
    Oder lass das jemanden machen und beobachte ihn dabei.

    Ich würde einen Geldschein solange rausgeben, solange der Geldsschein kleiner oder gleich dem Restbetrag ist.
    Dann mache ich mit dem nächsten kleineren Geldschein weiter.



  • @wob Hab vorher nur über Google gesucht, da habe ich hier nur einen halbwegs brauchbaren Eintrag gefunden.

    @SeppJ Ah okay, gut zu wissen. Danke 🙂

    Ich habe es jetzt wie folgt:

    if(rueckgeld > 0)
    {

    while(rueckgeld >= geld_100) 
    {
    
    rueckgeld = rueckgeld - 1 * geld_100;
    std::cout << "1x 100€ Schein" << '\n';
    
    }
    
    while(rueckgeld >= geld_50)
    {
    rueckgeld = rueckgeld - 1 * geld_50;
    std::cout << "1x 50€ Schein" << '\n';
    
    }
    

    ....

    Funktioniert und kann ich nachvollziehen. Jetzt muss ich nur noch die Beschränkung einbauen, dass jeder Schein nur 2 mal vorhanden ist. Hab jetzt gedacht, ich könnte um die while-Schleife noch eine for-Schleife setzen, sodass die while Schleife nur 2 mal durchlaufen werden kann, aber das funktioniert nicht so, wie ich es gerne hätte 😕


  • Mod

    Wenn man mehrmals (hier sogar sieben Mal!) fast den gleichen Code hat, dann ist das ein sicheres Zeichen dafür, dass man eine wichtige Abstraktion verpasst hat.

    Wenn du der Chef von einem menschlichen Kassierer wärst, und diesem erklären müsstest, was er zu tun hat, würdest du dann auch eine ganz lange Erklärung geben

    Zuerst nimmst du die 100er Scheine und versuchst so lange einen 100€ Schein raus zu geben, wie der Kunde noch mehr als 100€ bekommt.
    Dann nimmst du die 50er Scheine und versuchst so lange einen 50€ Schein raus zu geben, wie der Kunde noch mehr als 50€ bekommt.
    Dann nimmst du die 20er Scheine und versuchst so lange einen 20€ Schein raus zu geben, wie der Kunde noch mehr als 20€ bekommt



    Dann nimmst du die 1er Münzen und versuchst so lange eine 1€ Münze raus zu geben, wie der Kunde noch mehr als 1€ bekommt.

    ?
    Nein, das würdest du sicher einfacher erklären. Und bei einem Computerprogramm geht das dann auch einfacher.



  • @noaaah ist aber blöd, wenn du andere Geldscheine hast.

    Du solltest die Werte in einem Array unterbringen.

    int Scheine[] = { 100, 50, 20, 10, 5, 2, 1, 0};

    In einem zweiten Array kannst du dann noch den Vorrat unterbringen und runterzählen.



  • Relativ simple Möglichkeit:

    • Alles Geld in der Kasse in ein vector packen (siehe std::vector::push_back())
    • Sortieren (siehe std::sort)
    • grössten Schein dem Kunden geben, falls er noch was zu bekommen hat
    • dann Schein entfernen (siehe std::vector::pop_back())
    • wenn noch Scheine da und kunde noch was zu bekommen hat -> weitermachen


  • @TGGC sagte in Fahrkartenautomat; Rückgeld mit möglichst großen Scheinen zurückgeben:

    Relativ simple Möglichkeit:

    • Alles Geld in der Kasse in ein vector packen (siehe std::vector::push_back())
    • Sortieren (siehe std::sort)
    • grössten Schein dem Kunden geben, falls er noch was zu bekommen hat
    • dann Schein entfernen (siehe std::vector::pop_back())
    • wenn noch Scheine da und kunde noch was zu bekommen hat -> weitermachen

    Die Bedingung bei Schritt drei ist nicht korrekt, es müsste heissen:

    • grössten Schein dem Kunden geben, falls er noch mindestens so viel zu bekommen hat wie dieser Schein wert ist

    Ich dachte auch erst noch dass no ein Loop fehlt, aber ich nehme an du meinst mit "alles Geld" jeden einzelnen Schein - also auch mehrfach den selben Wert wenn es davon noch mehr als einen gibt. Und dann reicht das natürlich so.



  • Ja, so war es gemeint. Es sollte gar nicht irgendwie optimal oder so sein.



  • Cool, das ( Geldstückelung ) war mein erstes richtiges Programm was ich als Kind geschrieben habe. Damals noch in Basic 😉 Da war ich 10 oder 11 glaube...



  • Hi, da das Thema durch ist übernehme ich Mal. Gibt's eine Möglichkeit, dass mein Code in der Nähe der Lösung ist?

    #include <iostream>
    #include <vector>
    
    using namespace std;
    
        int temp;
        int bezahlung;
        float restgeld;
    	float kilometerpreis = 0.1;
    	float kosten = 0;
    	int entfernung = 0;
    	int scheinekapazitaet = 14;
    	vector<int>scheine = {1, 1, 2, 2, 5, 5, 10, 10, 20, 20, 50, 50, 100, 100};
    	vector<int>rueckscheine;
    
    void berechnung1 () {
    	kosten = entfernung * kilometerpreis;
    }
    
    void berechnung2 () {
    	restgeld = bezahlung - kosten;
    }
    
    int main () {
    
    	cout << "Fahrkartenautomat, bitte Entfernung eingeben " << endl << endl;
    
    	cin >> entfernung;
    		berechnung1();
    	
    	cout << "Der Preis betraegt: " << kosten << endl;    cout << "Wert fuer Bezahlung eingeben: " << endl;
    	
    	cin >> bezahlung;
    		berechnung2();
    	
    	cout << endl << endl;
    	for (vector<int>::iterator i = scheine.end(); scheine.end() != scheine.begin() ;i--) {
            if (restgeld >= (*i)) {
            	cout << "zZz" << endl;
            	//temp erhält wert von i?
            	temp = (*i);
            	//speicher an stelle von i wird gelöscht?
                scheine.pop_back();
                //neuer eintrag für rückscheinvektor
                rueckscheine.push_back(temp);
                //restgeld wird gemindert
                restgeld -= temp;
                //
            }
    	}
    	
    	cout << "test";
    
    	for (vector<int>:: iterator i = scheine.begin(); scheine.begin() != scheine.end(); i++) {
    		cout << "scheine " << (*i)<< endl;
    	}
    	
    	for (vector<int> :: iterator i; rueckscheine.begin() != rueckscheine.end(); i++) {
    		cout << "rueckscheine " << (*i) << endl;
    	}
    }
    

    Thx..


Log in to reply