Das Java-Praktikum

Werbung
D3kjd3Di38lk323nnm
26
8
S-Bahn in Byteburg
Diese Aufgabe scheint zunächst leicht lösbar zu sein, allerdings blähen sich unbedacht konstruierte Lösungen schnell auf. Die Struktur des Liniennetzes lässt
sich ausnutzen, um die verschiedenen Fahrpreisregeln mit einer passenden Abfolge von Tests sukzessive abzuspalten.
Das S-Bahn-Netz von »Byteburg« ist regelmäßig aufgebaut. Es gibt fünf Hauptlinien (»1« bis »5«) und eine Ringlinie. Linie »6« befindet sich im Bau und wird
noch nicht benutzt. Die Stationen entlang der Hauptlinien sind von innen nach
außen mit 1 bis 6 durchnummeriert. Im Zentrum liegt Station »00«. Die Ringlinie
verbindet reihum die Stationen 3 der Hauptlinien.
Die Stationen sind mit einem zweistelligen Code benannt: Die Zehnerstelle
nennt die Linie, die Einerstelle die Stationsnummer, wie in der folgenden Skizze
gezeigt:
66
56
16
15
14
65
55
5
13
63
54
61
52
45
46
4
51
11
00
41
42
43
44
25
23
12
62
53
26
1
6
64
22
2
24
21
31
32
33
34
3
35
36
Im Innenraum (grau hinterlegt) liegen das Zentrum und alle Stationen bis
einschließlich der Ringlinie. Die übrigen Stationen liegen im Außenraum.
Reinhard Schiedermeier / Klaus Köhler, Das Java-Praktikum, dpunkt.verlag, ISBN 978-3-89864-765-6
27
Schreiben Sie ein Programm ByteburgTarif, das die Fahrpreise nach den folgenden Regeln berechnet:
1. Eine Fahrt kostet 2 Taler1 (Beispiel: 11 nach 13).
2. Jede überquerte Zonengrenze kostet zusätzlich 1 Taler (Beispiel: 11 nach 14:
2 + 1 = 3 Taler).
3. Jede benutzte Endstation kostet zusätzlich 1 Taler (Beispiel: 16 nach 11: 2 +
1 (Zonengrenze) + 1 (Endstation) = 4 Taler).
4. Eine Fahrt zwischen zwei benachbarten Stationen kostet immer 1 Taler, auch
wenn eine Zonengrenze dazwischen liegt oder eine Endstation benutzt wird
(Beispiele: 13 nach 14, 15 nach 16 und 13 nach 53: jeweils 1 Taler).
Beachten Sie, dass nach Linie 6 auch noch weitere Hauptlinien geplant sind mit
jeweils 6 Stationen, die die Ringlinie an Station 3 schneiden. Auch nach Ausbauten bleiben die Hauptlinien im Uhrzeigersinn fortlaufend durchnummeriert. Ihr
Programm soll mit möglichst wenig Aufwand für die erweiterten Streckennetze
anpassbar sein.
Ihr Programm ByteburgTarif liest die Codes von zwei Stationen von der Kommandozeile und gibt die Fahrtkosten aus.
Beispiele:
$ java ByteburgTarif 11 13
2
$ java ByteburgTarif 13 14
1
$ java ByteburgTarif 00 16
4
Lösung
Eine wesentliche Anforderung ist die Flexibilität bezüglich des späteren Ausbaus
um weitere Linien. Die Anzahl der Linien, zugleich die höchste Nummer einer
Hauptlinie, wird in der Variablen lines gespeichert. Im weiteren Programm wird
nur noch lines verwendet. Sollten neue Linie gebaut werden, muss lediglich der
Startwert dieser Variablen angepasst werden.
int lines = 5;
...
1
»Taler« wird hier als beliebige Fantasiewährung verwendet.
28
8 S-Bahn in Byteburg
Zunächst werden die Kommandozeilenargumente verarbeitet und in Variablen
gespeichert:
int code1 = Integer.parseInt(args[0]);
int code2 = Integer.parseInt(args[1]);
...
Eine Fahrt kostet in jeder Richtung den gleichen Betrag. Die weitere Berechnung
fällt leichter, wenn der kleinere und der größere Code festgestellt werden:
int codemin = Math.min(code1, code2);
int codemax = Math.max(code1, code2);
...
Die Ziffern der Stationscodes können mit ganzzahliger Arithmetik getrennt werden. Linien- und Stationsnummern (Zehner- und Einerstellen der Codes) liegen
damit einzeln vor:
int
int
int
int
...
lineMin = codemin / 10;
stationMin = codemin % 10;
lineMax = codemax / 10;
stationMax = codemax % 10;
In der Variablen result wird der Fahrpreis berechnet:
int result;
...
Im Rest des Programms werden die verschiedenen Regeln zur Bestimmung des
Preises absteigend nach Vorrang überprüft.
Als Erstes sind Kurzfahrten zu behandeln. Eine Kurzfahrt kann entlang einer
Hauptlinie erfolgen. In diesem Fall sind die Zehnerstellen gleich und die größere
Einerstelle liegt um 1 über der kleineren, wie zum Beispiel 13 und 14:
// Kurzfahrt entlang einer Hauptlinie
if(lineMin == lineMax && stationMin + 1 == stationMax)
result = 1;
...
Eine Kurzfahrt kann auch entlang der Ringlinie verlaufen. Die Einerstellen sind
beide 3, die Zehnerstellen unterscheiden sich um 1, wie zum Beispiel 43 und 53:
// Kurzfahrt entlang der Ringlinie
else if(stationMin == 3 && stationMax == 3 && lineMin + 1 == lineMax)
result = 1;
...
Reinhard Schiedermeier / Klaus Köhler, Das Java-Praktikum, dpunkt.verlag, ISBN 978-3-89864-765-6
29
Noch nicht berücksichtigt ist der Fall, dass auf der Ringlinie von Hauptlinie 1
zur höchsten Hauptlinie gefahren wird. Wieder sind die Einerstellen beide 3. Die
kleinere Zehnerstelle ist 1; die größere entspricht der Anzahl Linien, wie zum
Beispiel 13 und 53:
// Kurzfahrt auf der Ringlinie von Linie 1 zur hoechsten Linie
else if(stationMin == 3 && stationMax == 3
&& lineMax == lines && lineMin == 1)
result = 1;
...
Schließlich kann eine Kurzfahrt zum Zentrum führen. Die Summe der Einerstellen
ist in diesem Fall 1:
// Kurzfahrt zum/vom Zentrum
else if(stationMin + stationMax == 1)
result = 1;
...
In allen anderen Fällen gilt der Grundpreis von 2 Taler, zuzüglich möglicher Aufschläge:
else {
result = 2;
...
// Grundpreis; Aufschläge folgen
Eine Zonengrenze wird überquert, wenn eine Stationsnummer im Innenraum liegt
und die andere im Außenraum:
if(stationMin < 4 && stationMax >= 4)
result++;
else if(stationMin >= 4 && stationMax < 4)
result++;
...
Wenn beide Stationsnummern im Außenraum liegen, müssen die Liniennummern
verglichen werden. Wenn sie verschieden sind, wurden zwei Zonengrenzen überquert, ansonsten keine:
else if(stationMin >= 4 &&
result += 2;
...
stationMax >= 4 && lineMax != lineMin)
30
8 S-Bahn in Byteburg
Schließlich sind noch Endstationen aufschlagspflichtig. Unabhängig voneinander
und unabhängig von den vorhergehenden Tests wird jede Stationsnummer mit 6
verglichen:
if(stationMin == 6)
result++;
if(stationMax == 6)
result++;
}
...
Am Ende wird der Fahrpreis ausgegeben:
System.out.println(result);
Hier der gesamte Algorithmus:
Lege die Anzahl Linien lines fest
Lies die beiden Stationscodes ein
Berechne die kleinere Liniennummer lineMin und deren Stationsnummer stationMin
Berechne die größere Liniennummer lineMax und deren Stationsnummer stationMax
Sind die Liniennummern gleich und die Stationsnummern um 1 verschieden?
Y
Preis = 1 Y
Sind beide Stationsnummern == 3 und die Liniennummern um 1 verschieden?
(Kurzfahrt)
Preis = 1 Y
Sind beide Stationsnummern == 3 und lineMin == 1 und lineMax == lines?
(Kurzfahrt)
Preis = 1 Y
Ist die Summe der Stationsnummern == 1?
(Kurzfahrt)
Preis = 1 Preis = 2
(Kurzfahrt)
Ist stationMin < 4
und stationMax > 3?
Y
Preis um 1
Ist stationMin > 3
erhöhen
und stationMax < 4?
Y
(Zonengrenze)
Preis um 1
Sind beide
erhöhen
Stationsnummern > 3
(Zonengrenze)
und die Liniennummern
verschieden?
Y
Preis um 2 erhöhen
(2 Zonengrenzen)
N
N
N
N
N
N
N
Ist stationMin == 6?
Y
Preis um 1 erhöhen
(Endstation)
N
Ist stationMax == 6?
Y
Preis um 1 erhöhen
(Endstation)
N
Preis ausgeben
Reinhard Schiedermeier / Klaus Köhler, Das Java-Praktikum, dpunkt.verlag, ISBN 978-3-89864-765-6
Herunterladen