Erste Schritte Wechselgeld berechen. Verbesserungsvorschläge

BombaX

Mitglied
Hallo,

mein Code ist voll Funktionstüchtig, aber ich bin überhaupt nicht zufrieden mit der Syntax.:oops:
Habt ihr Verbesserungsvorschläge? :toll:


Aufgabe Wechselgeld:

Wenn Sie in einem Geschäft an der Kasse Ihr Wechselgeld bekommen, gibt Ihnen der Kassenmitarbeiter zuerst Dollar, dann Quarter (25 Cent), dann Dime (10 Cent), dann Nickel (5 Cent) und schließlich Cent zurück. Zum Beispiel Sie bekommen 163 Cent zurück:

  • Ein Dollar passt in 163, Rest 63 Cent.
  • Zwei Quarter passen in 63 Cent, Rest 13 Cent.
  • Ein Dime passt in 13 Cent, Rest 3 Cent.
  • Es wird kein Nickel gebraucht.
  • Drei Cent bleiben übrig.



Wird in einer Main-Klasse ausgeführt ;)
Java:
package interaktiv;

import java.util.Scanner;

public class Wechelgeld {

    
    
    public void restGeld () {
        
    int dollar = 100, quarter = 25, dime = 10, nickel = 5, cent = 1;
    int eingabe ;
    
        Scanner scan = new Scanner (System.in) ;
        System.out.println("Bitte geben sie ihr Geld in Cent an:");
            eingabe = scan.nextInt();
            
        int ergebnisDollar = eingabe / dollar; 
            int moduloDollar = eingabe % dollar;
                    
        int ergebnisQuarter = moduloDollar / quarter;
            int moduloQuarter = moduloDollar % quarter;
                    
        int ergebnisDime = moduloQuarter / dime;
            int moduloDime = moduloQuarter % dime;
            
            
        int ergebnisNickel = moduloDime / nickel;
            int moduloNickel = moduloDime % nickel;
                    
        int ergebnisCent = moduloNickel / cent;
            int moduloCent = moduloNickel % cent;
            
            System.out.println("Du hast " + eingabe + " Cent eingegeben. \nDollar \t" + ergebnisDollar + "\nQuarter \t" +
                                ergebnisQuarter + "\nDime \t" + ergebnisDime + "\nNickel \t" + ergebnisNickel + "\nCent \t" + ergebnisCent);
         
        
        
        
    }
    
}
 

Fab1

Top Contributor
Hab jetzt nicht geschaut, ob die Lösung von dir stimmt, aber rein vom Aufbau sieht es doch gut aus. Bei so wenig Zeilen kann man ja auch nicht so viel falsch machen :)
 

BombaX

Mitglied
Ich meinte ob ich diesen Teil irgendwie zusammenfassen kann, oder ob es eine "kürzere" Lösung gibt.:toll:

Java:
 int ergebnisDollar = eingabe / dollar; 
            int moduloDollar = eingabe % dollar;
                    
        int ergebnisQuarter = moduloDollar / quarter;
            int moduloQuarter = moduloDollar % quarter;
                    
        int ergebnisDime = moduloQuarter / dime;
            int moduloDime = moduloQuarter % dime;
            
            
        int ergebnisNickel = moduloDime / nickel;
            int moduloNickel = moduloDime % nickel;
                    
        int ergebnisCent = moduloNickel / cent;
            int moduloCent = moduloNickel % cent;
 

Fant

Bekanntes Mitglied
Man kann das auch mit verschachtelten Schleifen lösen, aber so finde ich es eigentlich schöner und übersichtlicher.

Allerdings würde ich die Berechnung der Wechselgeld-Stückelung von der Ein- und Ausagbe komplett trennen.
Bei so kleinen Miniprogrammen ist aber auch das eigentlich egal.
 

Network

Top Contributor
Naja am besten noch
Java:
int dollar = 100, quarter = 25, dime = 10, nickel = 5, cent = 1;
Als Klassenvariable und als private final deklarieren.
Die Werte werden sich ja bestimmt ganz sicher nicht mehr ändern, deswegen die finaldeklaration. Sonst kommt irgendeiner daher und denkt sich er erhöht mal geschwind den Wert eines Dollars um dann mehr Geld herauszubekommen. Verhindert wird dass dann durch die final-deklaration. ODer evt. passiert das irgendwie ausversehen.
Als Klassenvariable, damit nicht ständig die Integers neu initialisiert werden müssen, bei jedem Aufruf.

Solche Systeme werden ja normalerweise für Bankautomaten geschrieben. Die haben jetzt aber nunmal keinen großen Prozessor und schnellen Arbeitsspeicher drin. Hört sich jetzt doof an, ich weiss, aber rein theoretisch würde das bedeuten, dass dann weniger Code in millionen Automaten ausgeführt werden müsste tausendmal am Tag = billigere Hardware benötigt für die Prozedur, geringere Stromkosten dass sich im Jahr auf Milliarden aufsummieren kann an Extraverlust für den Anbieter... Moment was war gleich nochmal die Frage? :D

Dann noch Wechselgeld mit S schreiben, die Einrückungen richtig machen der Integers (wenn du obigen Tip keine Beachtung schenken solltest ;)), die Logik selbst am Code mit der Berechnung kann man kaum kürzer schreiben. Du kannst es anderst schreiben bzw. andere Lösungsansätze verwenden, aber nichts davon wird kürzer sein als dein jetziges Ergebniss.

Gruß
Net
 

AquaBall

Top Contributor
(Aus Langeweile, ... und während ich auf Antworten auf meine eigene Frage warte ...):
Zwar kein Stück kürzer, aber die eigentliche Prozedur auf 1 Schleife reduziert.
Java:
import java.util.ArrayList;
import java.util.Scanner;
class Coin{
	private String name;
	private int value;
	public int used=0;
	public Coin(String name, int value) {this.name = name; this.value = value; }
	public String getName() 	{ return name; }
	public int getValue() 		{ return value; }
	public int getUsed() 		{ return used; }
	public void setUsed(int used){ this.used = used; }
}

public class WechselGeld {
	public static void main(String[] args) {
		ArrayList<Coin> coinList= new ArrayList<Coin>();
		coinList.add(new Coin("dollar", 100));
		coinList.add(new Coin("quarter", 25));
		coinList.add(new Coin("dime", 10));
		coinList.add(new Coin("nickel", 5));
		coinList.add(new Coin("cent", 1));
		
		Scanner scan = new Scanner (System.in) ;
		System.out.println("Bitte geben sie ihr Geld in Cent an:");
		int eingabe = scan.nextInt();

		int rest=eingabe;
		for (Coin coin:coinList) {
			coin.setUsed(rest / coin.getValue()); 
			rest %=coin.getValue();
		}
		System.out.println("Du hast " + eingabe + " Cent eingegeben.");
		for (Coin coin:coinList) System.out.println(coin.getName() + "\t"+ coin.getUsed()); 
	}
}

An deinem eigenen Code würde ich ändern:
[*] Der RestBetrag muss ja nicht jedesmal neu angelegt werden
[*] (Und in solchen Fällen halte ich eine einzeilige Eingabe für legitim.)
Java:
	int rest = eingabe;
	int ergebnisDollar = rest / dollar; 	rest %=dollar;
	int ergebnisQuarter = rest / quarter; 	rest %=quarter;
	int ergebnisDime = rest/ dime; 			rest %=dime;
	int ergebnisNickel = rest / nickel; 	rest %=nickel;
	int ergebnisCent = rest / cent;
 
Zuletzt bearbeitet:
K

kaschik

Gast
Für die Münzen eine eigene Klasse zu erstellen, ist schon eine gute Idee. Noch besser wäre jedoch eine Enumeration:

Java:
public class Wechselgeld {
	public static void main(String[] args) {
		System.out.print("Bitte geben Sie Ihr Geld in Cent an: ");
		int input = new Scanner(System.in).nextInt();
		
		int tmp = input;
		for (Coins c : Coins.values()) {
			c.count = tmp / c.value;
			tmp %= c.value;
		}
		
		for (Coins c : Coins.values())
			System.out.println(c + "\t" + c.count);
	}
}

enum Coins {
	DOLLAR(100), QUARTER(25), DIME(10), NICKEL(5), CENT(1);

	int value;
	int count;

	private Coins(int value) {
		this.value = value;
	}
}
Wenn man es schön machen will, dann kann man dem Enum noch getter/setter und eine toString-Methode spendieren, aber der Vorteil einer Enumeration gegenüber eine Klasse sollte offensichtlich geworden sein.
 

Landei

Top Contributor
Egal welche Lösung du nun am besten findest (AquaBalls sieht für mich etwas over-engineered aus, kaschiks finde ich bis auf einige Variablennamen recht gut), beachte bitte unbedingt das Single Responsibility Principle. Der Wikipedia-Artikel spricht zwar nur von Klassen, aber es ist genauso auf Methoden anwendbar:

Jede Klasse und jede Methode sollte genau eine klar definierte Aufgabe haben.

Deine Methode macht drei Dinge: Betrag abfragen, berechnen und ausgeben. Das sind zwei Dinge zuviel. Insbesondere beschränkst du selbst deine Flexibilität, wenn du etwas berechnest und sofort ausgibst. Was ist, wenn du das Ergebnis stattdessen einmal anderswo (etwa in der [c]toString[/c]-Methode) benötigst?

Normalerweise ist es eine gute Idee, entweder eine Methode etwas berechnen und zurückgeben zu lassen, oder eine Methode etwas ändern oder ausgeben zu lassen, aber beides nicht in einer einzigen Methode zu vermischen.

Java:
import java.util.Scanner;

public class Wechselgeld {

    public void restGeld() {
        int betragInCent = frageGeldInCent();
        int[] wechselGeld = berechneWechselGeld(betragInCent);
        zeigeErgebnis(betragInCent, wechselGeld[0], wechselGeld[1], wechselGeld[2], wechselGeld[3], wechselGeld[4]);
    }

    private int frageGeldInCent() {
        Scanner scan = new Scanner(System.in);
        System.out.println("Bitte geben sie ihr Geld in Cent an:");
        return scan.nextInt();
    }

    private int[] berechneWechselGeld(int betragInCent) {
        int[] werte = {100, 25, 10, 5, 1};
        int[] wechselGeld = new int[5];
        int restBetrag = betragInCent;
        for (int i = 0; i < werte.length; i++) {
            wechselGeld[i] = restBetrag / werte[i];
            restBetrag = restBetrag % werte[i];
        }
        return wechselGeld;
    }

    private void zeigeErgebnis(int betragInCent, int dollar, int quarter, int dime, int nickel, int cent) {
        System.out.printf("Du hast %d Cent eingegeben.", betragInCent);
        System.out.printf("Das sind %d Dollar, %d Quarter, %d Dime(s), %d Nickel und %d Cent.%n",
                dollar, quarter, dime, nickel, cent);
    }
}

Die vielen Methoden in meiner Lösung sind nur auf den ersten Blick "unübersichtlich", denn sie sind kurz, und man kann mit einen Blick sehen, was sie tun. Insbesondere reicht es, auf den Namen und die Argumentliste zu schauen, um ihre Aufgabe zu erkennen. Bei dir funktioniert das nicht
 
Zuletzt bearbeitet:
K

kaschik

Gast
@Landei: Bei deiner Lösung geht leider der Bezug zwischen Münzenname und -wertigkeit total verloren. Würde man das Programm beispielsweise auf Euro ändern wollen, wäre das mit einem erheblichen Aufwand verbunden.
 

Landei

Top Contributor
Das ist korrekt, aber man will ja die armen Anfänger nicht gleich erschlagen. Im richtigen Leben böte sich z.B. eine Map an, oder man schreibt einen eigenen Datentyp wie du (wobei ein enum schon wieder zu unflexibel sein kann, es sei denn es implementiert ein entsprechendes Interface)
 

Landei

Top Contributor
Etwa so:
Java:
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Scanner;

public class Wechselgeld {

    private final Map<String, Integer> wechselMap;

    public Wechselgeld() {
        wechselMap = new LinkedHashMap<String, Integer>();
        wechselMap.put("Dollar", 100);
        wechselMap.put("Quarter", 25);
        wechselMap.put("Dime(s)", 10);
        wechselMap.put("Nickel", 5);
        wechselMap.put("Cent", 1);
    }

    public void restGeld() {
        int betragInCent = frageGeldInCent();
        Map<String, Integer> wechselGeld = berechneWechselGeld(betragInCent);
        zeigeErgebnis(betragInCent, wechselGeld);
    }

    private int frageGeldInCent() {
        Scanner scan = new Scanner(System.in);
        System.out.println("Bitte geben sie ihr Geld in Cent an:");
        return scan.nextInt();
    }

    private Map<String, Integer> berechneWechselGeld(int betragInCent) {
        int restBetrag = betragInCent;
        Map<String, Integer> wechselGeld = new LinkedHashMap<String, Integer>();
        for (Map.Entry<String, Integer> eintrag : wechselMap.entrySet()) {
            wechselGeld.put(eintrag.getKey(), restBetrag / eintrag.getValue());
            restBetrag = restBetrag % eintrag.getValue();
        }
        return wechselGeld;
    }

    private void zeigeErgebnis(int betragInCent, Map<String, Integer> wechselGeld) {
        System.out.println("Du hast " + betragInCent + " Cent eingegeben.");
        String zwischen = "Das sind ";
        for (Map.Entry<String, Integer> eintrag : wechselGeld.entrySet()) {
            System.out.print(zwischen);
            zwischen = ", ";
            System.out.print(eintrag.getValue() + " " + eintrag.getKey());
        }
    }
}

Die [c]LinkedHashMaps[/c] sind wichtig, da ja die Reihenfolge beibehalten werden muss.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
H Mergesort aufwand berechen Java Basics - Anfänger-Themen 5
V Datentypen Position mit Int und Float berechen und ausgeben Java Basics - Anfänger-Themen 5
S Ende des Tages in Java berechen. Java Basics - Anfänger-Themen 3
G Woche berechen Java Basics - Anfänger-Themen 4
B Datum: Differenz in Tagen berechen Java Basics - Anfänger-Themen 3
T Differenz berechen Java Basics - Anfänger-Themen 14
N BMI Rechner Was haltet ihr von dem Code habt ihr Verbesserungsvorschläge weil design teschnisch ist das nicht das geilste würde das gerne überarbeiten Java Basics - Anfänger-Themen 12
D Verbesserungsvorschläge zur Struktur einer Client Server Desktop Chat App Java Basics - Anfänger-Themen 24
Vivien Bitte um Optimierungsvorschläge / Verbesserungsvorschläge / allgemeines Feedback Java Basics - Anfänger-Themen 8
N Verbesserungsvorschläge zu Wegfinder Programm Java Basics - Anfänger-Themen 26
S verbesserungsvorschläge? Java Basics - Anfänger-Themen 19
fLooojava first project - Verbesserungsvorschläge am Code Java Basics - Anfänger-Themen 8
Z Zahl Pi probabilistisch berechnen (Kritik/Verbesserungsvorschläge) Java Basics - Anfänger-Themen 4
D Verbesserungsvorschläge zum Quellcode Java Basics - Anfänger-Themen 15
M Bitte um Verbesserungsvorschläge Java Basics - Anfänger-Themen 14
L Suche Verbesserungsvorschläge für mein erstes Programm Java Basics - Anfänger-Themen 34
Chucky Einfacher Taschenrechner Verbesserungsvorschläge Java Basics - Anfänger-Themen 13

Ähnliche Java Themen

Neue Themen


Oben