Vorwort

Vorwort
Reinhard Schiedermeier ist Professor an der Hochschule München, Fakultät für Informatik und Mathematik. Er beschäftigt sich
mit Programmiersprachen, Compilerbau und Webtechnologien.
Nach Informatikstudium und Promotion an der Universität Erlangen-Nürnberg arbeitete er in der Forschung bei Siemens-Nixdorf
und IBM.
Klaus Köhler ist Professor an der Hochschule München, Fakultät
für Informatik und Mathematik. Dort lehrt er schwerpunktmäßig
Softwareentwicklung, Künstliche Intelligenz und Kryptografie. Vorher war er Dozent bei der Siemens AG in München. Er hat an der
RWTH Aachen und an der Chalmers TH Göteborg studiert und in
Mathematik promoviert.
Reinhard Schiedermeier · Klaus Köhler
Das Java-Praktikum
Aufgaben und Lösungen
zum Programmierenlernen mit Java 7
2., aktualisierte und erweiterte Auflage
Reinhard Schiedermeier
[email protected]
Klaus Köhler
[email protected]
Lektorat: Dr. Michael Barabas
Copy-Editing: Ursula Zimpfer, Herrenberg
Satz: Science & More
Herstellung: Birgit Bäuerlein
Umschlaggestaltung: Helmut Kraus, www.exclam.de
Druck und Bindung: M.P. Media-Print Informationstechnologie GmbH, 33100 Paderborn
Bibliografische Information der Deutschen Nationalbibliothek
Die Deutsche Nationalbibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie;
detaillierte bibliografische Daten sind im Internet über http://dnb.d-nb.de abrufbar.
ISBN:
Buch 978-3-89864-765-6
PDF 978-3-86491-056-2
ePub 978-3-86491-057-9
2., aktualisierte und erweiterte Auflage 2011
Copyright © 2011 dpunkt.verlag GmbH
Ringstraße 19 B
69115 Heidelberg
Die vorliegende Publikation ist urheberrechtlich geschützt. Alle Rechte vorbehalten. Die Verwendung
der Texte und Abbildungen, auch auszugsweise, ist ohne die schriftliche Zustimmung des Verlags
urheberrechtswidrig und daher strafbar. Dies gilt insbesondere für die Vervielfältigung, Übersetzung
oder die Verwendung in elektronischen Systemen.
Es wird darauf hingewiesen, dass die im Buch verwendeten Soft- und Hardware-Bezeichnungen sowie
Markennamen und Produktbezeichnungen der jeweiligen Firmen im Allgemeinen warenzeichen-,
marken- oder patentrechtlichem Schutz unterliegen.
Alle Angaben und Programme in diesem Buch wurden mit größter Sorgfalt kontrolliert. Weder Autor
noch Verlag können jedoch für Schäden haftbar gemacht werden, die in Zusammenhang mit der
Verwendung dieses Buches stehen.
543210
v
Vorwort
Learning by doing – einen besseren Leitspruch könnte es zum Lernen von Programmieren kaum geben.
Programmieren lernen hat viel Ähnlichkeit mit Schwimmen lernen in Kindertagen. Man kann einem Kind noch so genau erklären, wie man Arme und Beine
im Takt bewegt, im richtigen Moment ein- und ausatmet, den Kopf anhebt oder
loslässt und so weiter – schwimmen kann das Kind mit diesen Einsichten ganz
bestimmt nicht! Dazu muss es ins Wasser springen, nass werden, husten, nach
Luft japsen, untergehen und wieder auftauchen. Die Begeisterung durchläuft dabei sicher einige Höhen und auch unvermeidliche Tiefen.
Das Gleiche gilt für das Programmieren: Man kann sich beliebig lang die
Konzepte, Strukturen, Ausdrucksmittel und Paradigmen von Programmiersprachen durchlesen oder erklären lassen – programmieren lernt man damit nicht.
Dazu muss man Code schreiben, Fehler machen, suchen und beheben, Hilfe holen, sich andere Programme ansehen und so weiter. Bezüglich der Begeisterung
gilt dabei das oben Gesagte.
Dieses Buch will Ihnen helfen, Java programmieren zu lernen. Sie finden hier
eine Sammlung von ausgewählten Aufgaben und dazu jeweils einen ausführlich
erklärten Lösungsvorschlag. Betrachten Sie es im übertragenen Sinn als eine Kombination aus Sprungbecken, Schwimmreifen und Wellenmaschine.
Inhalt
Die Aufgaben in diesem Buch setzen Kenntnisse von Java voraus. Dieses Wissen
wird hier nicht erklärt, sondern praktisch angewendet. Es ist unbedingt zu empfehlen, dass Sie gleichzeitig eine einschlägige Vorlesung besuchen oder ein JavaLehrbuch heranziehen, wie zum Beispiel [Mössenböck 11], [Schiedermeier 10]
oder eines der vielen anderen.
Der Schwierigkeitsgrad der Aufgaben in diesem Buch steigt fortlaufend an
und bezieht schrittweise immer neue Sprachmittel von Java ein. Die folgende Liste
gibt Ihnen einen Überblick über die Auswahl der Aufgaben und die Voraussetzun-
vi
Vorwort
gen zur Lösung.1 Eine genauere Liste der einzelnen Aufgaben und Teilaufgaben
mit ihrem Schwierigkeitsgrad und den jeweils im Fokus stehenden Sprachmitteln
finden Sie in Anhang B (Seite 430).
I. Arithmetik, Variablen, Wertzuweisungen Die ersten Aufgaben kommen mit
elementaren Kenntnissen von Java aus. Sie erwarten nicht mehr als Arithmetik, Variablen und Ausgabeanweisungen.
II. Kontrollstrukturen Die Aufgaben in diesem Abschnitt führen Alternativen
und Schleifen ein. Diese Sprachmittel werden als Kontrollstrukturen bezeichnet. Praktisch alle verbreiteten Programmiersprachen bieten sie in ganz ähnlicher Form an.
III. Algorithmen In diesem Abschnitt werden Kontrollstrukturen zur Lösung algorithmisch anspruchsvollerer Aufgaben eingesetzt. Zum Teil werden geschachtelte Schleifen verwendet, ebenso wie Arrays und Rekursion.
IV. Klassen Der nächste Abschnitt beschäftigt sich mit der Definition und dem
Einsatz von Klassen. Die Algorithmik tritt dabei etwas in den Hintergrund.
Das Augenmerk liegt hier auf dem Umgang mit Objekten, Methoden und
der Abgrenzung von Zuständigkeiten. Alle diese Maßnahmen zielen auf die
systematische Konstruktion größerer Programme ab.
V. Interfaces und Vererbung Hier kommen Interfaces und Vererbung als Kern
der Objektorientierung ins Spiel. Der disziplinierte Einsatz von Vererbung
in ihren verschiedenen Facetten führt zu eleganten und flexiblen Lösungen.
Aber ebenso kann Vererbung bei unangemessener Verwendung heilloses Chaos auslösen. Diese Aufgaben erfordern sorgfältige Modellierung des Problems
in aufeinander abgestimmte Typen und den Entwurf passender Methoden.
VI. Containerklassen Eine wichtige Art von Klassen sind Containerklassen, das
heißt Klassen, die andere Elemente organisieren und verwalten. Hier wird das
Collection-Framework benutzt und es werden auch neue Containerklassen
erstellt.
VII. I/O, Netzwerke, Nebenläufigkeit Die Aufgaben dieses Abschnittes widmen
sich pragmatischen Themen wie der Ein- und Ausgabe. Der Umgang mit externen Daten und dem Filesystem ist nicht ganz einfach, aber in der Praxis
unverzichtbar. Weitere Aufgaben haben Netzwerkprogrammierung zum Gegenstand. Diese Art von Problemen ist von Natur aus nebenläufig und legt
den Einsatz von Threads nahe.
VIII. Generics Die Aufgaben im letzten Abschnitt befassen sich mit generischen
Klassen und Typen. Diese Sprachmittel sind äußerst nützlich und führen zu
robusten und kompakten Programmen.
1Viele Aufgaben bestehen aus mehreren Teilaufgaben, die die ursprüngliche Problemstellung in der einen oder anderen Richtung ausweiten. In solchen Fällen sind gelegentlich
Vorgriffe auf Sprachmittel nötig, die erst weiter hinten in den Mittelpunkt rücken. Nehmen Sie sich bitte die Freiheit, solche Vertiefungen im ersten Anlauf zu übergehen. Sie
können später jederzeit wieder darauf zurückkommen.
Vorwort
vii
Eine Standardinstallation von Java beinhaltet eine umfangreiche Laufzeitbibliothek, die wohl kaum noch jemand in allen Einzelheiten überblickt.2 Programmieren mit Java erfordert sicher nicht, die komplette Bibliotheksreferenz im Kopf zu
haben. Die meisten Aufgaben sind deshalb so gestaltet, dass sie sich mit möglichst
wenigen und elementaren Bibliotheksklassen lösen lassen. Ausnahmen sind Containerklassen im Collection-Framework sowie die Themen I/O und Netzwerkkommunikation, die ohne Bibliotheksunterstützung nicht sinnvoll zu behandeln
sind.3 Im Mittelpunkt steht allerdings immer die Sprache Java. Es reicht völlig
aus, wenn Sie aus diesem Buch mitnehmen, dass es für gewisse Teilprobleme Hilfe in der Bibliothek gibt. Zu gegebener Zeit schlagen Sie in der ausgezeichneten
Onlinereferenz nach oder besuchen eine der zahlreichen Quellen im Internet, wie
zum Beispiel [Almanac 02] oder [Tutorial].
Bedienungsanleitung
Neben den Aufgaben enthält dieses Buch auch alle Lösungen. Wiederkehrende
und nebensächliche Teile der Lösungen, wie zum Beispiel der Kopf der mainMethode oder import-Klauseln, sind zum Teil nicht abgedruckt. Die vollständig
ausformulierten, sofort übersetzbaren Lösungen finden Sie auf der Webseite zum
Buch: http://sol.cs.hm.edu/dpunkt-java-praktikum .
Wir sind uns bewusst, dass die unmittelbar auf den Aufgabentext folgende
Lösung recht verführerisch ist. Dennoch sollten Sie, lieber Leser4, versuchen, den
maximalen Nutzen aus diesem Buch zu ziehen, und die mitgelieferte Lösung so
lange wie möglich ignorieren. Blättern oder lesen Sie bitte erst dann weiter, wenn
Sie selbst eine befriedigende Lösung entwickelt haben oder wenn Sie unbedingt
einen Hinweis brauchen.
Zur Lösung der Aufgaben implementieren Sie lauffähige Programme. Konzepte oder Ideen reichen leider nicht aus, denn deren Tragfähigkeit bleibt ungewiss, bis sie mit einer konkreten Realisierung nachgewiesen wird. Geben Sie sich
deshalb bitte nicht mit der Annahme zufrieden, dass Sie die Lösung im Ernstfall
schon finden würden. Einige Aufgaben weisen verborgene Klippen auf, die erst
bei der praktischen Umsetzung zutage treten.
Wenn Ihnen die richtige Idee einfach nicht kommen will, möchten wir Ihnen
empfehlen, wenigstens eine Nacht über einer Aufgabe zu schlafen (oder schlaflos
über dem Problem zu brüten), bevor Sie die Lösung nachschlagen.
2Einige Java-Versionen unterscheiden sich überwiegend im Umfang der Bibliothek.
Merkliche Änderungen der Sprache Java gab es in Java 1.5 und 1.7. Java 1.5 wurde,
mehr aus Marketing-strategischen Gründen, in »Java 5« umbenannt. Damit begann eine
neue Versionszählung, in der die vormalige Major version 1 weggefallen ist.
3Eine kompakte, aber für den Zweck dieser Aufgaben ausreichende Darstellung finden
Sie beispielsweise in [Mössenböck 11], Kap. 21.
4Wo immer in diesem Buch auf Personen Bezug genommen wird, sprechen wir immer Frauen und Männer in bestimmten Rollen gleichermaßen an. Wir verzichten um der
Lesbarkeit willen auf sperrige Formulierungen wie »Leser/Leserin«.
viii
Vorwort
Betrachten Sie die abgedruckten Lösungen im Buch nur als Vorschläge, aber
nicht als das Maß aller Dinge. Die Aufgaben lassen zum Teil viel Spielraum bei
der Wahl des Lösungsweges. Deshalb ist es vollkommen in Ordnung, wenn Sie
zu einer ganz anderen Lösung kommen.
In der Java-Programmierung haben sich im Laufe der Zeit einige Konventionen entwickelt, die den test of time bestanden haben und deshalb allgemein
akzeptiert werden. In Anhang C haben wir einige Regeln zusammengestellt, die
wir bei der Entwicklung unserer Lösungen beachtet haben. Es wäre sicher hilfreich, wenn Sie diesen Anhang durchsehen, bevor Sie die Aufgaben angehen. Es
macht nichts, wenn Sie zunächst noch nicht alles verstehen. Wichtig ist nur, dass
Sie sich wieder daran erinnern, zu diesem oder jenem Punkt etwas gelesen zu
haben. Sie werden auch feststellen, dass wir selbst gelegentlich gegen die Konventionen verstoßen. Konventionen sind nicht in Marmor gemeißelt, sondern spielen
mehr die Rolle von Empfehlungen, von denen man durchaus mit guten Gründen
abweichen kann.
Einige Aufgaben erfordern den Einsatz von Bibliotheksklassen und
-methoden, deren Beherrschung zwar nützlich, aber aus konzeptioneller
Sicht wenig tiefschürfend ist. Um Ihnen die Arbeit zu erleichtern, finden Sie in
Anhang D kurze Programme, die einfache, wiederkehrende Aufgaben erledigen,
wie zum Beispiel das Einlesen einer Textdatei oder den Transport von Daten
über ein Netzwerk. Benutzen Sie diese Programme nach Bedarf als Bausteine für
Ihre eigenen Lösungen.
Technische Voraussetzung
Die minimalen Hilfsmittel zur Bearbeitung der Aufgaben sind ein einfacher Texteditor und ein Java-Entwicklungssystem. Ein Texteditor5 wird mit jedem Betriebssystem geliefert. Etwas komfortablere Editoren, die oft die Entwicklung von JavaProgrammen unterstützen, sind für die meisten populären Plattformen frei verfügbar, wie zum Beispiel jEdit oder Joe.
Ein Java-Entwicklungssystem kann kostenlos von der Website der Firma
Oracle heruntergeladen werden (http://java.oracle.com). Sie finden auf dieser
Website eine ganze Anzahl von Downloads. Die folgenden Kriterien führen Sie
zum passenden Paket:
Version Es gibt verschiedene Java-Versionen. Sie brauchen Java Version 7 oder
eine nachfolgende Version.6
5Ein Textverarbeitungssystem, wie Microsoft Word oder OpenOffice, eignet sich
schlecht.
6Mit Versionen 5 und 6 können die Aufgaben gelöst werden, allerdings sind nicht alle
Lösungen im Buch und auf der Webseite damit übersetzbar. Version 1.4 oder noch ältere
Versionen reichen nicht aus.
Vorwort
ix
Edition Java wird für unterschiedliche Einsatzzwecke angeboten. Für den persönlichen Gebrauch vorgesehen ist die Standard Edition (SE). Die ebenfalls verfügbare Enterprise Edition (EE) und die Micro Edition (ME)
sind für andere Systeme ausgelegt und bieten hier keinen Vorteil.
Entwicklungssystem
Die Standard Edition ist als Java SE Development Kit (JDK) und als
Java SE Runtime Environment (JRE) verfügbar. Mit dem Runtime Environment JRE können zwar fertige Java-Programme ausgeführt, aber
keine neuen entwickelt werden. Sie brauchen deshalb das Development
Kit JDK, das das JRE komplett enthält.
Elegant lässt sich mit einer integrierten Entwicklungsumgebung (IDE) arbeiten.
Derzeit populär sind beispielsweise Eclipse und Netbeans, die beide kostenlos
und für praktisch alle Systeme verfügbar sind. Diese Umgebungen kapseln Editor,
Compiler, Laufzeitsystem und weitere Werkzeuge in einer ansprechenden grafischen Oberfläche, die viele Aufgaben automatisch oder mit Mausklick erledigt.
Darin liegt allerdings auch eine gewisse Gefahr, denn ohne Kenntnis der tatsächlichen Abläufe ist der Benutzer hilflos, wenn die IDE einmal nicht so reagiert wie
erwartet.
IDEs sind selbst umfangreiche Programme, deren Arbeitsweise verstanden
werden will und entsprechende Einarbeitung erfordert. Insgesamt sehen sich gerade Anfänger mit einer Komplexität konfrontiert, die ohne IDE vielleicht leichter
und schneller zu bewältigen wäre.
Behalten Sie schließlich im Auge, dass eine hübsche IDE zwar technische Abläufe vereinfacht, aber bei konzeptioneller Arbeit keine Unterstützung leistet. So
reduziert sich die Zeiteinsparung auf die Codierung, während die vorausgehende, oft entscheidende Denkarbeit unverändert überwiegend im Kopf stattfindet,
allenfalls unterstützt von Papier und Bleistift.7
Insgesamt sollten Sie abwägen, ob Sie die erste Zeit Ihres Vorhabens nicht
vielleicht auf eine IDE verzichten sollten, um die tatsächlichen Abläufe und Werkzeuge ungefiltert kennenzulernen. Sobald Ihre Programme aus mehreren Quelltextdateien bestehen, ist die Zeit möglicherweise reif für eine IDE.
Aufbau der Lösungen
Viele Lösungen werden schrittweise aufgebaut. Dabei wird das endgültige Programm aus kurzen Abschnitten zusammengesetzt, die jeweils einzeln diskutiert
und erklärt werden. Um nicht beim Einfügen jedes neuen Fragments alle zuvor
entwickelten Fragmente wiederholen zu müssen, werden die einzelnen Auszüge
mit Kommentartiteln versehen, auf die von anderer Stelle Bezug genommen wird.
Hier ein Beispiel für ein Codefragment:
// Berechnen der Summe s aller Zahlen von 1 bis n
7Vom zu frühen Einsatz bildschirmgestützter Entwurfswerkzeuge (UML-Editoren und
dergleichen) raten wir ab. Sie leisten gute Dienste zu Dokumentationszwecken, lenken aber
von der eigentlich wichtigen Denkarbeit ab.
x
Vorwort
int s =
int i =
while(i
s =
i =
}
0;
1;
<= n) {
s + i;
i + 1;
Später wird anstelle dieses Codeabschnitts nur noch der Kommentar genannt und
von drei Punkten gefolgt. Dieser Kommentar ist ein Platzhalter für das vorher
gezeigte Codefragment, das hier nicht mehr abgedruckt ist:
// Festlegen der Obergrenze n
int n = 10;
// Berechnen der Summe s aller Zahlen von 1 bis n
...
// Summe ausgeben
System.out.println(s);
Manche Lösungen werden sequenziell entwickelt. Ein Codefragment endet dann
mit drei Punkten, um anzuzeigen, dass das Programm noch nicht komplett ist
und weiter unten fortgesetzt wird.
// Variablen zur Berechnung der Zahlensumme
int n = 10;
// Obergrenze, bis zu der addiert wird
int s = 0;
// akkumulierte Summe
int i = 1;
// Zahl, die gerade addiert wird
...
Das nachfolgende Fragment setzt das oben begonnene Fragment fort:
// die Zahlen von 1 bis n addieren
while(i <= n) {
s = s + i;
i = i + 1;
}
// Summe ausgeben
System.out.println(s);
Wenn die einzelnen Abschnitte hintereinander zusammengesetzt werden, ergibt
sich das vollständige Programm.
Vorwort
xi
Auswahl der Aufgaben
Sie finden in diesem Buch ein breites Spektrum von Themen. Die zur Lösung erforderlichen Sprachmittel überspannen einen weiten Bereich. In dem Maße, wie
Sie Ihre Kenntnisse erweitern, werden immer neue Aufgaben zugänglich. Um Ihnen die Orientierung zu erleichtern, finden Sie im Anhang B die Sprachmittel, die
jeweils im Mittelpunkt der verschiedenen Aufgaben stehen.
Die Auswahl der Aufgaben ist unbestreitbar subjektiv. Einige Aspekte der
Sprache Java und weite Bereiche der Bibliothek von Java werden nicht erwähnt,
obwohl sie zweifellos wichtig sind. Wir haben uns auf Themen beschränkt, die
nach unserer Erfahrungen bei der Softwareentwicklung immer wieder auftauchen oder grundsätzliche Strukturen der Programmiersprache betreffen, deren
Verständnis für einen sicheren Umgang mit Java notwendig ist.
Wir hoffen natürlich, lieber Leser, dass möglichst alle Aufgaben in diesem
Buch Sie ansprechen. Allerdings ist diese Hoffnung wahrscheinlich vermessen,
deshalb wären wir bereits sehr zufrieden, wenn Ihnen ein großer Teil der Aufgaben zusagt.
Fassen Sie bitte die Aufgaben nicht als Test oder Prüfung auf, sondern als Anregung zum Grübeln und Tüfteln. Sicher wird Ihnen nicht jedes Mal in wenigen
Minuten die vollständige Lösung gelingen. Wenn Sie stehenden Fußes alle Aufgaben lösen könnten, dann hätten Sie dieses Buch ohnedies nicht nötig :-) Nehmen
Sie also in Kauf, dass es manchmal ein wenig dauert, bis Ihnen der entscheidende
Einfall kommt.
Webseite zum Buch
Unter der Internetadresse
http://sol.cs.hm.edu/dpunkt-java-praktikum
finden Sie weiteres Material zum Buch. In erster Linie stehen dort für Sie die
vollständigen, lauffähigen Lösungen zum Download zur Verfügung.
Dank
Unser Dank gilt den Mitarbeitern des dpunkt.verlages, die uns viel Freiheiten
bei der Gestaltung des Buches gelassen haben. Besonders danken möchten wir
Tschucky (Gudrun Schiedermeier), die sich in mühseliger Arbeit durch ständig
neue, unausgegorene Fassungen dieses Buches gearbeitet hat und Aufgaben lösen musste, die nicht immer lösbar waren. Schließlich sollen auch die Studenten8
unserer Fakultät 07 für Informatik und Mathematik der Hochschule München
gewürdigt werden, die über viele Semester hinweg in Prüfungen und Praktika
mit früheren Versionen der Aufgaben9 die Klingen kreuzten. Sie fanden manche
8Wie bereits weiter vorne ausgeführt steht eine solche Bezeichung für Personen beiderlei
Geschlechts, die die betreffende Rolle innehaben.
9Einige Aufgaben in diesem Buch beruhen auf Ideen, die als Übungsaufgaben in
[Schiedermeier 10] zu finden sind.
xii
Vorwort
überraschenden und kreativen Lösungen, die zum Teil in dieses Buch eingeflossen
sind.
Anregungen, Kritik und Verbesserungsvorschläge sind uns jederzeit willkommen. Bitte richten Sie Ihre Nachricht an [email protected] oder [email protected]
München, Frühjahr 2008
Klaus Köhler und Reinhard Schiedermeier
Vorwort zur 2. Auflage
Seit den Erscheinen der ersten Auflage in 2008 hat sich Java mit der Veröffentlichung von Version 7 im Sommer 2011 weiterentwickelt. Neben kleineren
syntaktischen Vereinfachungen erlaubt vor allem das »automatische Ressourcenmanagement« (ARM, try-with-resource) robusteren und kompakteren Code. Die
Codefragmente im Buchtext und der komplette Code auf der Webseite zum Buch
wurden an die neuen Möglichkeiten angepasst. Zum Übersetzen der Lösungsbeispiele ist infolgedessen allerdings ein Java SE Development Kit (JDK) der Version
7 erforderlich.
Inhaltlich sind sowohl einige komplett neue Aufgaben dazugekommen wie
auch eine Reihe von Erweiterungen bestehender Aufgaben. In vielen Lösungen
wurden statische UML-Klassendiagramme10 eingefügt, die das Zusammenspiel
verschiedener Interfaces und Klassen veranschaulichen. Selbstredend wurden alle
bekannten Fehler der ersten Auflage korrigiert.
Wir möchten an dieser Stelle den in der ersten Auflage ausgesprochenen Dank
auf Rebecca Neigert ausdehnen, die findige und interessante Ideen zu diesem Buch
beigetragen und mit scharfem Blick Schwachstellen im Text entdeckt hat.
Material zu diesem Buch finden Sie weiterhin auf der Internetseite
http://sol.cs.hm.edu/dpunkt-java-praktikum
Anregungen,
Kritik
und
Verbesserungsvorschläge
senden
Sie
bitte
an
[email protected] oder [email protected]
München, Sommer 2011
Klaus Köhler und Reinhard Schiedermeier
10Eine kurze Einführung in Unified Modeling Language gibt beispielsweise [Inden 11].
xiii
Inhaltsverzeichnis
Vorwort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
I Arithmetik, Variablen, Wertzuweisungen
v
1
1
Dreiecksfläche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2
2
2.1
2.2
Datumsarithmetik . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Wochentag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Osterdatum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
5
6
3
Dutzend, Schock, Gros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8
II Kontrollstrukturen
11
4
Median . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
5
Mäxchen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
6
Flaggen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
7
Rechtecke . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
8
S-Bahn in Byteburg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
9
9.1
9.2
Newton-Verfahren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Approximation der Quadratwurzel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Kubikwurzel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
10
Zahlenbasis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
11
Messwerte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
xiv
Inhaltsverzeichnis
12
12.1
12.2
12.3
Reihen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Exponentialfunktion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Hyperbolischer Sinus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Umkehrfunktion des hyperbolischen Sinus . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
13
Potenzieren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
III
Algorithmen
49
14
Kompression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
15
15.1
15.2
15.3
15.4
15.5
Perfekte und andere Zahlen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Perfekte Zahlen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Befreundete Zahlen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Quersumme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Lychrel-Zahlen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Fröhliche Zahlen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
16
16.1
16.2
16.3
16.4
Binomialkoeffizienten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Iterative Berechnung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Rekursive Berechnung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
Pascal’sches Dreieck . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Optimierte Berechnung des Pascal’schen Dreiecks . . . . . . . . . . . . . . . . . . . . 75
17
Teppiche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
18
18.1
18.2
18.3
18.4
18.5
18.6
Primzahlen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
Exakter Primzahltest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
Probabilistischer Primzahltest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
Primzahlen-Iterator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Goldbach-Vermutung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
Generator zu einer Primzahl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
Zufallszahlengenerator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
19
19.1
19.2
19.3
Permutationen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Permutationsvektoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Permutationsmatrizen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
Sudoku . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
20
20.1
20.2
Kommentar-Zapper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
Blockkommentare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
Zeilenkommentare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
Inhaltsverzeichnis
21
21.1
21.2
IV
xv
Mustervergleich . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
Jokerzeichen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
Super-Joker . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
Klassen
115
22
22.1
22.2
Punkte und Dreiecke . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
Punkte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
Dreiecke . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
23
Intervalle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
24
Uhrzeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
25
Große Ganzzahlen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
26
26.1
26.2
Polynom . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
Polynomklasse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
Division von Polynomen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
27
27.1
27.2
Boolean-Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
Direkte Umsetzung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
Logische Operatoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
28
Josephusring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
29
29.1
29.2
E-Camel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
Kamele und Karawanen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
Robuste Implementierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
V
Interfaces und Vererbung
179
30
30.1
30.2
Mobiles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
Sterne und Stäbchen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
Glitzersterne . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
31
31.1
31.2
31.3
31.4
Kobolde . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Zahlen-Kobolde . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Zähe Kobolde . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Kobold-Verhalten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Ehrliche Kobolde . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
188
188
190
192
196
xvi
Inhaltsverzeichnis
32
32.1
32.2
Widerstandsnetzwerke . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
Konstante Widerstände . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
Potenziometer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
33
33.1
33.2
33.3
Stoppuhren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Basisklasse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Zurücksetzen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Pauseknopf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
34
Spielkarten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
35
35.1
35.2
Zahlenfolgen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
Konkrete Folgen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
Filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
36
36.1
36.2
36.3
36.4
36.5
Chiffren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Substitutionschiffren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Xor-Substitution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Additive Substitution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Stromchiffren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Diffie-Hellman . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
37
Bäume . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
38
38.1
38.2
38.3
Physikalische Größen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Längen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Allgemeine Größen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Zusammengesetzte Einheiten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
VI Containerklassen
209
209
211
213
234
235
236
238
238
240
252
252
255
258
263
39
39.1
39.2
39.3
Buchstabensammlungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Sammlung beliebiger Buchstaben . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Sammlung ohne Duplikate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Sammlung als Collection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
264
264
271
273
40
Vorlesungsverzeichnis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
41
41.1
41.2
41.3
41.4
Römische Zahlen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Klasse für römische Zahlen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Stringdarstellung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Vergleich . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Einsatz eines Aufzählungstyps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
42
Zählerlisten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
282
282
285
287
290
Inhaltsverzeichnis
VII
xvii
I/O, Netzwerke, Nebenläufigkeit
305
43
43.1
43.2
43.3
Textdateien . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Textzeilen-Iterator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Zeilentransformator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Textdatei-Trenner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
306
306
310
312
44
44.1
44.2
I/O-Filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
Textposition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
Zeichen umdrehen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319
45
45.1
45.2
45.3
45.4
Filesystemsuche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Rekursiver Directory-Durchlauf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Directory-Tiefe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Dubletten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Umfang von Verzeichnissen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
46
46.1
46.2
Bitstreams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329
Einfache Bitstreams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329
Beliebig lange Bitstreams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
47
Tittle-Tattle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338
48
Watchdog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343
49
Verkehrsüberwachung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348
50
50.1
50.2
50.3
Nameservice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Nameserver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Persistenter Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Nameclient . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
355
355
359
360
51
51.1
51.2
51.3
Vorlesungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Mathe-Vorlesung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Observer mit mehreren Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Wait & Notify . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
363
364
368
374
322
322
325
325
327
xviii
VIII
Inhaltsverzeichnis
Generics
377
52
52.1
52.2
Objektpaare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378
Generische Klasse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378
Vergleich von Paaren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380
53
53.1
53.2
53.3
Generische Methoden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
No Null . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Median . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Klon-Armee . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
382
382
383
385
54
54.1
54.2
54.3
Relationen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Aufgezählte Relation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Reflexivität, Symmetrie und Transitivität . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Verkettete Relation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
387
387
390
391
55
Ring-Queue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 394
56
56.1
56.2
56.3
Listen und Warteschlangen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Geordnete Listen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Geordnete Warteschlangen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Iteratoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
399
399
402
404
57
57.1
57.2
57.3
57.4
57.5
Algebraische Strukturen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Gruppe, Ring und Körper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Der Körper Z2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Aufzählungstyp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Der Körper Zp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Polynomringe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
407
408
409
412
413
416
IX
Anhang
419
A
Glossar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420
B
Schwerpunkte der Aufgaben . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430
C
Konventionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 434
D
Programmfragmente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441
Literaturverzeichnis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448
Teil I
Arithmetik, Variablen,
Wertzuweisungen
2
1
Dreiecksfläche
In dieser Aufgabe müssen mathematische Ausdrücke, wie man sie in einer Formelsammlung findet, in Java-Syntax »übersetzt« werden. Man sollte sich Bibliotheksmethoden zunutze machen, die häufig wiederkehrende Berechnungen und
Funktionen zur Verfügung stellen. Zwischenergebnisse werden in temporären
Variablen gespeichert, um Berechnungen nicht unnötig zu wiederholen.
Schreiben Sie ein Programm TriangleArea, das die Fläche eines Dreiecks berechnet
und ausgibt. Ein Dreieck ist durch die Eckpunkte A(ax , ay ), B(bx , by ), C(cx , cy )
festgelegt. In mathematischen Formelsammlungen finden Sie dafür verschiedene
Formeln.
Die kartesischen Koordinaten ax , ay , bx , by , cx , cy der Eckpunkte werden in
dieser Reihenfolge als sechs Floatingpoint-Werte auf der Kommandozeile angegeben. Lesen Sie diese Werte zunächst in lokale Variablen ein und verarbeiten Sie
diese dann weiter. Zum Einlesen des Kommandozeilenargumentes mit Index a1
als Floatingpoint-Wert verwenden Sie folgenden Anweisung:
Double d = Double.parseDouble(args[a]);
Für das Dreieck A(−1, 0), B(0, 2), C(1, 0) berechnet das Programm zum Beispiel2
die Fläche 2.0:
$ java TriangleArea -1 0 0 2 1 0
2.0
B
A
C
1Das erste Kommandozeilenargument hat den Index 0, das zweite den Index 1 und so
weiter.
2Das $-Zeichen am Zeilenanfang ist das Promptzeichen einer Unix-Shell. Ihr System
zeigt wahrscheinlich ein anderes Prompt. Den Text nach dem Promptzeichen geben Sie
ein. Die darunter folgenden Zeilen, in diesem Beispiel nur eine, gibt das Programm aus.
3
Auch für »entartete« Fälle arbeitet das Programm korrekt:
$ java TriangleArea 0 0 1 1 2 2
0.0
$ java TriangleArea 0 0 0 0 1 1
0.0
$ java TriangleArea 1 1 1 1 1 1
0.0
// alle drei Punkte auf einer Linie
// zwei Punkte fallen zusammen
// alle drei Punkte fallen zusammen
Lösung
Das Programm wird als main-Methode in der Klasse TriangleArea definiert:
public class TriangleArea {
public static void main(String[] args) {
...
Zuerst werden die Kommandozeilenparameter in entsprechende lokale Variablen
übertragen:
int i = 0;
double ax =
double ay =
double bx =
double by =
double cx =
double cy =
Double.parseDouble(args[i++]);
Double.parseDouble(args[i++]);
Double.parseDouble(args[i++]);
Double.parseDouble(args[i++]);
Double.parseDouble(args[i++]);
Double.parseDouble(args[i++]);
Die Heronische Formel liefert die Fläche eines Dreiecks
A = s(s − a)(s − b)(s − c)
, wobei a, b, c die Seitenlängen sind.
mit s = a+b+c
2
Die Seitenlängen können aus den Eckpunktkoordinaten mit der Methode
Math.hypot berechnet werden.3
double a = Math.hypot(cx - bx, cy - by);
double b = Math.hypot(ax - cx, ay - cy);
double c = Math.hypot(bx - ax, by - ay);
...
3hypot berechnet aus den zwei Katheten eines rechtwinkligen Dreiecks die Hypotenuse
(Pythagoras).
4
1 Dreiecksfläche
Aus den Seitenlängen ergeben sich s und die Fläche:
double s = (a + b + c)/2;
double area = Math.sqrt(s*(s - a)*(s - b)*(s - c));
...
Schließlich wird die berechnete Fläche ausgegeben:
System.out.println(area);
}
}
Die wiederholte Angabe des Präfixes Math. kann wegfallen, wenn zu Beginn des
Programms alle Bibliotheksmethoden der Klasse java.lang.Math mit einer statischen Importklausel4 zugänglich gemacht werden:
import static java.lang.Math.*;
Der Hauptteil des Programms kürzt sich dann zu:
...
double
double
double
double
double
...
a = hypot(cx - bx,
b = hypot(ax - cx,
c = hypot(bx - ax,
s = (a + b + c)/2;
area = sqrt(s*(s -
cy - by);
ay - cy);
by - ay);
a)*(s - b)*(s - c));
4Der Begriff »Klausel« bezeichnet eine Anweisung, die nur den Compiler betrifft. Klauseln haben keine Auswirkung auf die Effizienz des übersetzten Codes.
5
2
Datumsarithmetik
Zur Lösung dieser beiden Aufgaben werden komplizierte Formeln mit historischer Bedeutung in Java-Syntax ausgedrückt. Dabei wird die ganzzahlige Division und der Modulus-Operator (%) benutzt. Erstere wirkt auf den ersten Blick
etwas ungewohnt, weil sie aus rechnerischer Sicht augenscheinlich falsche Ergebnisse produziert. Hier wird aber genau diese Funktionalität gebraucht. Der
etwas undurchsichtige Ablauf der Berechnungen macht die Fehlersuche nicht
ganz leicht.
2.1
Wochentag
Der Geistliche Christoph Zeller hat 1885 eine Formel aufgestellt, die für ein gegebenes Kalenderdatum den Wochentag liefert. Die Zeller’sche Formel lautet:
w = (d +
26·(m+1)
10
+
5·y
4
+
c
4
+ 5 · c − 1) mod 7
Dabei sind:
d
m
y
c
w
Tag im Monat (1 ≤ d ≤ 31)
Monat (3 ≤ m ≤ 14). In die Formel müssen Januar und Februar
als Monate 13 und 14 des Vorjahres eingesetzt werden.
Jahr im Jahrhundert (0 ≤ y ≤ 99)
Jahrhundert
Index des Wochentages, gezählt ab 0 = Sonntag bis 6 = Samstag
Alle Divisionen sind ganzzahlig.
Schreiben Sie ein Programm Zeller, das drei Zahlen für Tag, Monat und Jahr
von der Kommandozeile akzeptiert, die mit der beschriebenen Umrechnung ein
Datum benennen. Das Programm gibt den Index des entsprechenden Wochentages aus. Hier Beispiele für den 23. August 1959 und den 6. Februar 2000, beides
Sonntage:
$ java Zeller 23 8 1959
0
$ java Zeller 6 14 1999
0
6
2 Datumsarithmetik
Lösung
Aus den drei Kommandozeilenargumenten werden zunächst d, m, y und c berechnet. Jahrhundertzahl und Jahr im Jahrhundert ergeben sich aus der Jahreszahl durch ganzzahlige Division durch 100 beziehungsweise als Rest bei Division
durch 100:
int
int
int
int
int
d = Integer.parseInt(args[0]);
m = Integer.parseInt(args[1]);
temp = Integer.parseInt(args[2]); // Jahreszahl
y = temp%100;
c = temp/100;
Die Formel lässt sich geradlinig in Java umsetzen:
int w = (d + 26*(m + 1)/10 + 5*y/4 + c/4 + 5*c - 1)%7;
In dieser Form muss der Anwender die Sonderbehandlung von Januar und Februar bei der Eingabe berücksichtigen. Mit einer if-Abfrage direkt nach der Initialisierung von temp kann das Programm diese Umrechnung selbst erledigen:
...
int temp = Integer.parseInt(args[2]);
if(m < 3) {
m += 12;
// Januar --> 13, Februar --> 14
temp--;
// zurück zum Vorjahr
}
int y = ...
Der Wochentag des 6. Februar 2000 kann jetzt ohne Sonderbehandlung des Februars berechnet werden:
$ java Zeller 6 2 2000
0
2.2
Osterdatum
Das Osterdatum ist festgelegt auf den ersten Sonntag nach dem ersten Vollmond
nach der Tag-und-Nacht-Gleiche im Frühling. Es ergibt sich für das Jahr y (4stellige Angabe) mit der folgenden Berechnung. Die Divisionen sind ganzzahlig
und ignorieren den Divisionsrest.1
1Diese Berechnung funktioniert nur im gregorianischen Kalender, der seit 1582 gilt.
Für frühere Jahre kann das Programm nicht verwendet werden.
2.2 Osterdatum
7
g = y mod 19
y
c = 100
h = (c − 4c − 8c+13
25 + 19g + 15) mod 30
h
29
(1 − h+1
· 21−g
i = h − 28
11 )
y
j = (y + 4 + i + 2 − c + 4c ) mod 7
l =i−j
m = 3 + l+40
44
d = l + 28 − 31 m
4
Am Ende liefern die Variablen d (Tag) und m (Monat) das Datum des Ostersonntags.
Schreiben Sie ein Programm EasterDate, das auf der Kommandozeile eine Jahreszahl y ≥ 1582 erhält und Tag und Monat des Ostersonntags in diesem Jahr
ausgibt.
Zum Beispiel fiel im Jahr 2008 Ostern auf den 23. März, 2009 war Ostern
am 12. April:
$ java EasterDate 2008
23 3
$ java EasterDate 2009
12 4
Lösung
Die Java-Implementierung der Berechnungen setzt die Formeln direkt in arithmetische Ausdrücke um:
int
int
int
int
int
int
int
int
int
y
g
c
h
i
j
l
m
d
=
=
=
=
=
=
=
=
=
Integer.parseInt(args[0]);
// eine Jahreszahl
y%19;
y/100;
// Jahrhundert
(c - c/4 - (8*c + 13)/25 + 19*g + 15)%30;
h - (h/28)*(1 - (29/(h + 1))*((21 - g)/11));
(y + y/4 + i + 2 - c + c/4)%7;
i - j;
3 + (l + 40)/44;
// Ostermonat
l + 28 - 31*(m/4);
// Ostersonntag
8
3
Dutzend, Schock, Gros
Die folgende Aufgabe lässt sich durch geschickten Einsatz des ModulusOperators und der ganzzahligen Division lösen. Es wird deutlich, dass die beiden
Operatoren eng zusammenhängen und nutzbringend Hand in Hand arbeiten.
Am Ende ergibt sich eine recht einfache Implementierung, die ohne ModulusOperator deutlich umständlicher ausfällt.
In früheren Zeiten waren verschiedene Zählmaße gebräuchlich:
1 Dutzend
= 12 Stück
1 Schock
= 5 Dutzend
= 60 Stück
1 Gros
= 12 Dutzend
= 144 Stück
Schreiben Sie ein Programm Zaehlmass1, das eine gegebene Anzahl in Gros,
Schock, Dutzend und Einzelstücke umrechnet. Einige Beispiele:
100 Stück
= 1 Schock + 3 Dutzend + 4 Stück
200 Stück
= 1 Gros + 4 Dutzend + 8 Stück
300 Stück
= 2 Gros + 1 Dutzend
Ihr Programm liest eine ganze Zahl n ≥ 0 von der Kommandozeile und gibt vier
Werte für die Anzahl Gros, Schock, Dutzend und Einzelstücke aus (alle ≥ 0).2
Einige Aufrufbeispiele:
$
0
$
1
$
2
java Zaehlmass 100
1 3 4
java Zaehlmass 200
0 4 8
java Zaehlmass 300
0 1 0
1Java erlaubt beliebige Unicode-Zeichen in Klassen- und Dateinamen, auch deutsche
Umlaute. Der Klassenname »Zählmaß« wäre also zulässig. Allerdings ist die Codierung
derartiger Zeichen in Dateinamen plattformspezifisch, deshalb werden sie hier vermieden.
Die ausgeschriebenen Umlaute sind zwar weniger schön, aber problemlos und portabel.
2Im Ergebnis sollen möglichst große Zählmaße benutzt werden. Die Umrechnungen
300 Stück = 25 Dutzend oder 300 Stück = 5 Schock wären also nicht gewünscht.
9
Lösung
Hier lässt sich der Zusammenhang zwischen Modulus und ganzzahliger Division
nutzen.3 Der Java-Ausdruck a/b liefert den ganzzahligen Quotienten ab , der Ausdruck a%b den Divisionsrest. Zunächst wird mit gros = n/144 bestimmt, wie viele
ganze Gros in die Gesamtzahl n passen. Der Rest von n%144 wird dann nach dem
gleichen Verfahren weiter in die kleineren Zählmaße gestückelt, bis am Ende nur
noch Einzelstücke übrig bleiben:
int n = Integer.parseInt(args[0]);
int gros = n/144;
n = n%144;
int schock = n/60;
n = n%60;
int dutzend = n/12;
n = n%12;
int stueck = n;
System.out.printf("%d %d %d %d%n", gros, schock, dutzend, stueck);
3Bei negativen Operanden des Modulus-Operators ist Vorsicht geboten. Das Ergebnis
hat immer das Vorzeichen des ersten Operanden, kann also negativ werden. In dieser
Aufgabe spielt das aber keine Rolle, weil keine negativen Operanden vorkommen.
Teil II
Kontrollstrukturen
12
4
Median
Ziel der Aufgabe ist eine möglichst sparsame Implementierung, die keine unnötigen Tests ausführt. Dabei wird (hoffentlich) deutlich, dass sich eine Lösung
besser im Kopf als an der Tastatur entwerfen lässt. Obwohl sich im vorliegenden Fall kaum ein messbarer Laufzeitgewinn erzielen lassen wird, sollte eine
»gute« Lösung möglichst keinen Code duplizieren oder die gleichen Ausdrücke
mehrfach berechnen.
Schreiben Sie ein Programm Median, das drei verschiedene ganze Zahlen a, b, c
von der Kommandozeile einliest und den mittleren der drei Werte ausgibt. Damit
gemeint. Denken Sie sich a, b und
ist nicht der arithmetische Mittelwert a+b+c
3
c der Größe nach geordnet. Das Programm gibt den Wert aus, der dann in der
Mitte steht. Hier einige Beispiele:
$
2
$
2
$
2
$
2
java Median 1 2 3
java Median 2 1 3
java Median 2 3 1
java Median 2 1 2
Versuchen Sie mit möglichst wenig Vergleichen, mit einfachen Bedingungen und
ohne Bibliotheksmethoden auszukommen.
Lösung
Die drei Zahlen werden in Variablen a, b, c gespeichert.
public class Median {
public static void main(String[] args) {
int a = Integer.parseInt(args[0]);
int b = Integer.parseInt(args[1]);
int c = Integer.parseInt(args[2]);
...
Was this manual useful for you? yes no
Thank you for your participation!

* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project

Download PDF

advertisement