-------------------------------------------------------------------------------- Money2.txt -------------------------------------------------------------------------------- Beispiel: Nr. 1132 (Geldberechnung) Autor: Thomas Terényi E-Mail: thomas.terenyi@iname.com Matr.nr.: e0225440 Datum: 23.10.2002 Source: Money2.java Beschreibung: Ein Geldbetrag wird eingelesen und auf Scheine und Münzen aufgeteilt. -------------------------------------------------------------------------------- Auszug aus der Spezifikation -------------------------------------------------------------------------------- 1.) Aufgabenstellung: Lesen Sie einen String ein, der einen Geldbetrag sowie eines der (fiktiven) Währungskennzeichen C und D enthält. In diesen fiktiven Währungen gibt es folgende Scheine und Münzen: C = Scheine (2,10,50,100,500,800) Münzen (1,5) D = Scheine (4,20,50,100,400) Münzen (1,2,5,10) Der Geldbetrag soll nun auf möglichst wenige (große) Scheine aufgeteilt werden; Münzen dürfen erst dann genommen werden, wenn man mit Scheinen nicht mehr weiterkommt. Auch hier sollen es möglichst wenige Münzen sein. 2.) Eingabedaten: Lesen Sie einen String ein, der einen Geldbetrag und am Ende einen der Buchstaben "C" oder "D" enthält. Es dürfen nur Ziffern sowie die Großbuchstaben C und D im String vorkommen. Der Geldbetrag muß größer als 0 sein und darf 10000000 (10 Millionen) nicht übersteigen. 3.) Ausgabedaten: Bei korrekten Eingabesätzen soll Ihr Programm die Aufteilung des Betrages in Scheine und Münzen liefern. Geben Sie dazu ein "S" aus, danach in nach Betrag absteigender Reihenfolge den Nennwert des Scheines und die Anzahl der notwendigen Scheine dieser Größe. Ebenso verfahren Sie mit den Münzen: Geben Sie ein "M" aus und danach Nennwert und Anzahl der benötigten Münzen. Wenn überhaupt keine Scheine bzw. Münzen notwendig sind, so geben Sie auch kein "S" bzw. "M" aus. Trennen Sie die einzelnen Teile der Ausgabe durch Leerzeichen und geben Sie am Ende einen Zeilenvorschub aus. 4.) Fehlerbehandlung: Bei fehlerhaften Eingabestrings geben Sie die Meldung "FALSCHE EINGABE", gefolgt von einem Zeilenvorschub, aus. 5.) Beispiele: Eingabe: 1253D Ausgabe: S 400 3 50 1 M 2 1 1 1 Eingabe: 31402C Ausgabe: S 800 39 100 2 2 1 -------------------------------------------------------------------------------- Beschreibung des Algorithmus -------------------------------------------------------------------------------- Der gesamte Algorithmus ist in der statischen Methode "main" der Klasse "Money2" implementiert. Die Aufgabenstellung wird in mehreren Schritten gelöst (siehe auch Kommentare im Source): 1.) Schleifenzähler deklarieren In Zeile 17 wird die Integer-Variable "i" deklariert, die im Folgenden bei allen Schleifen als Laufvariable verwendet wird. 2.) Eingabe einlesen Hier wird der Eingabestring mittels "readWord" eingelesen und in der String-Variable "eingabe" gespeichert. Zusätzlich wird noch die Länge (Anzahl der Zeichen des eingegebenen Strings) ermittelt und in der Variable "laenge" gespeichert. 3.) Eingabe überprüfen (nur Ziffernteil) Die Schleife in diesem Teil (Zeile 24-28) überprüft alle Zeichen, bis auf das letzte (dieses soll ja ein Buchstabe sein, der die Währung kennzeichnet) -- daher läuft die Schleife auch von "0" bis "laenge-1" -- mittels "isDigit", ob es eine Ziffer ist, da der Geldbetrag nur aus Ziffern bestehen kann. Falls ein ungültiges Zeichen angetroffen wird, wird die Schleife abgebrochen (Zeile 27). Danach wird überprüft, ob der Schleifenzähler ("i") ungleich dem Endwert ("laenge-1") ist. Ist dies der Fall, ist die Schleife nicht bis zum Ende gelaufen, d.h. sie wurde frühzeitig abgebrochen, als ein ungültiges Zeichen angetroffen wurde. Gleichzeitig wird auch überprüft, ob die Länge der eingegebenen Zeichenfolge größer als 9 Zeichen ist. Da der Betrag nicht 10 Millionen (= 8 Zeichen) überschreiten und das Kennzeichen der Währung nur ein Buchstabe (= 1 Zeichen) sein darf, kann die Gesamtlänge auf keinen Fall 9 Zeichen übersteigen. Tritt zumindest einer dieser Fälle auf -- Schleifenzähler nicht gleich dem Endwert, da ein ungültiges Zeichen gefunden wurde ODER ("||") der Eingabestring ist länger als 9 Zeichen und damit zu lang), dann wird die Fehlermeldung ausgegeben und das Programm beendet. 4.) Währung einlesen Das letzte Zeichen des eingegebenen Strings (das ist das Zeichen mit dem Index "laenge-1", da mit Null zu zählen begonnen wird, d.h. das erste Zeichen hat den Index "0", das zweite "1" etc.) wird hier in der Variable "waehrung" gespeichert. 5.) Währung überprüfen Nun wird das Kennzeichen der Währung überprüft. Ist es ungleich "D" UND ("&&") auch ungleich "C", ist es ungültig und die Fehlermeldung wird ausgegeben und das Programm beendet. 6.) Werte der Scheine entsprechend der Währung initialisieren Hier werden zuerst für Scheine und Münzen je zwei Arrays deklariert (Zeile 47-51). Danach werden diese Arrays je nach Inhalt der Variable "waehrung" (also der gewählten Währung) mit den entsprechenden Werten gefüllt (Zeile 55-59 bzw. Zeile 63-67). Die Arrays "scheinWert" und "muenzenWert" enthalten (in absteigender Reihenfolge!) die Werte der in der gewählten Währung vorhandenen Scheine bzw. Münzen. Dies heißt z.B.: Der Ausdruck "muenzenWert = new int[]{5,1};" bedeutet, dass es eine Münze mit dem Wert "5" und eine mit dem Wert "1" in der dieser Währung gibt. Die Arrays "scheinAnz" und "muenzenAnz" speichern, wie oft ein bestimmter Schein bzw. eine bestimmte Münze bei der Aufteilung des gesamten Geldbetrags verwendet wird. Dabei entspricht das erste Element des Arrays "scheinAnz" demjenigen Schein, dessen Wert im ersten Element des Arrays "scheinWert" gespeichert ist usw. Allgemein gilt also: Der Schein mit dem Wert "scheinWert[n]" wurde "scheinAnz[n]" mal verwendet. Analog verhält es sich bei den Münzen. Dies heißt z.B.: Wie oft die Münze mit dem Wert "5" (dem entspricht "muenzenWert[0]") verwedet wird, steht in "muenzenAnz[0]". Da hier der Geldbetrag noch nicht aufgeteilt worden ist, werden die Arrays "scheinAnz" und "muenzenAnz" mit den Startwert "0" initialisiert, da bis jetzt noch kein Schein und keine Münze verwendet wurde. Wichtig ist, dass die Arrays für Werte und Anzahl gleich viele Elemente haben, da es für jeden Schein und jede Münze aus den Arrays "scheinWert" und "muenzenWert" eine entsprechende Anzahl, wie oft der Schein bzw. die Münze verwendet werden soll, in den Arrays "scheinAnz" bzw. "muenzenAnz" gibt. 7.) Betrag einlesen Als nächstes wird die Zeichenfolge, die den Geldbetrag darstellt und aus dem ersten bis zum inkl. vorletzten Zeichen des eingelesenen Strings besteht, durch "parseInt" in eine Zahl umgewandelt und in der Integer-Variablen "betrag" gespeichert, um damit rechnen zu können. Normalerweise sollte "parseInt" in einem try-Block stehen, da diese Methode eine Exception wirft, falls die in eine Zahl umzuwandelnde Zeichenfolge ungültige Zeichen enthält. Hier wurde aber schon sicher- gestellt, dass der zu konvertierende String nur Ziffern enthält und dass er nicht länger als 8 Zeichen ist, die Zahl daher nicht 99999999 überschreiten kann (vgl. Schritt 3). Da also bekannt ist, dass der Geldbetrag nur gültige Zeichen enthält und mit einer Größe von max. 99999999 leicht im Wertebereich des Typs Integer liegt, kann die Übersetzung vom String in eine Zahl nicht fehlschlagen und "parseInt" keine Exception werfen. Eine andere Möglichkeit wäre gewesen Schritt 3 wegzulassen und die Überprüfung des Geldbetrages implizit über "parseInt" durchzuführen. 8.) Betrag überprüfen Hier wird getestet, ob der Geldbetrag im spezifizierten gültigen Bereich liegt. 9.) Anzahl der jeweiligen Scheine und Münzen berechnen In diesem Schritt findet nun die eigentliche Berechnung zur Aufteilung des Betrags auf Scheine und Münzen statt. Zuerst werden die Variablen "scheineVorhanden" und "muenzenVorhanden" deklariert und auf "false" initialisiert. Sie geben an, ob im Endergebnis überhaupt zumindest ein Schein bzw. eine Münze vorhanden ist, denn nur dann soll ein "S" bzw. ein "M" ausgegeben werden. Die äußere Schleife (Zeile 84-93) durchläuft alle Scheine, wobei in der inneren Schleife (Zeile 86-92) vom aktuellen Geldbetrag solange der Wert des momentanen Scheines subtrahiert wird, solange der Betrag noch größer oder gleich dem Wert des Scheins ist. Ist der Betrag größer als der Wert des aktuellen Scheins, so wird dieser Wert vom Betrag abgezogen und die Anzahl des entsprechenden Scheins um eins erhöht, da dieser gerade "verwendet" worden ist (Zeile 88-91). Zusätzlich wird "scheineVorhanden" auf "true" gesetzt, da gerade ein Schein "ausgegeben" wurde. Wird dieser Punkt nie erreicht, wird auch kein einziger Schein verwendet und "scheineVorhanden" bleibt "false". Kurz gesagt heißt das, jeder Schein wird so oft, wie möglich "verwendet" und da die Scheine im Array "scheinWert" in absteigender Reihenfolge angeordnet sind, wird sichergestellt, dass insgesamt möglichst wenige Scheine ausgegeben werden. Danach (Zeile 95-104) wird die Berechnung für die Münzen analog durchgeführt. Dadurch, dass zuerst schon alle Scheine "ausgereizt" worden sind, ist sichergestellt, dass nur öglichst wenige Münzen verwendet werden müssen. 10.) Ausgabe formatieren Nun kann nach erfolgter Berechnung der Ausgabestring formatiert werden. Dazu wird zuerst die Variable "ausgabe" deklariert und mit dem leeren String initialisiert. Dann werden, falls überhaupt Scheine auszugeben sind (Zeile 109), alle Scheine durchlaufen (Zeile 113) und falls der aktuelle Schein mindestens einmal verwendet wurde (Zeile 114), der Wert des Scheins und die Anzahl seines Vorkommens an den Ausgabe-String angehängt (Zeile 115). Da die Scheine im Array "scheinWert" schon absteigend nach Wert geordnet sind, ist auch gleich die Anforderung, das Ergebnis in dieser Reihenfolge auszugeben, erfüllt. Analog ist die Vorgehensweise für die Münzen. 11.) Ausgabe ausgeben Zum Schluss wird der fertig formatierte String mit dem Ergebnis ausgegeben. --------------------------------------------------------------------------------