Programmentwicklung I für Hörer anderer Fachrichtungen -Sommersemester 2003Abschlussklausur 22.10.2003 Name : Vorname : Matrikelnummer : Hauptfach : Nebenfach/Fachrichtung Hinweise : 1. Überprüfen Sie anhand der aufgedruckten Seitennummern 1 - 18 die Vollständigkeit Ihres Klausurtextes. 2. Hilfsmittel: bis zu 4 Seiten DIN A4 mit Notizen nach Wahl. Aufgabe Thema maximale Punktzahl erreichte Punktzahl 1 Basiswissen (allgemein) 0 x 2 Applikationen, Methoden 6 ok 3 Methoden (einfache Variable) 0 ok 4 Methoden, Felder 12 ok 5 Rekursion 9 ok 6 Basiswissen (Objektorientierung) 6 ok 7 Klassen, Vererbung ? ok 60 1. Klausur Übung/Praktikum Summe -1- Aufgabe 1 (5 Punkte ) Kennzeichnen Sie die folgenden Aussagen durch Ankreuzen als „wahr“ oder „falsch“. Bewertung: keine Antwort: 0 Punkte richtige Antwort: +0.5 Punkte falsche Antwort: -0.5 Punkte Minimal können 0 Punkte erreicht werden. wahr falsch -2- Aufgabe 2 ( 3 + 3 = 6 Punkte ) a) Schreiben Sie eine Java-Applikation, die sowohl die Anzahl als auch die Längen der übergebenen Kommandozeilenargumente auf dem Terminal ausgibt. Beispiel: Ist A2a die fragliche Applikation, so soll java A2a Das ist ein Testbeispiel die Ausgabe 4 3 3 3 12 liefern. -3- Aufgabe 2 (Fortsetzung) b) Schreiben Sie eine Java-Methode, die den durch nebenstehendes Flussdiagramm beschriebenen Algorithmus realisiert. Hinweise: 1. Alle vorkommenden Variable sind ganzzahlig 2. n soll als Parameter übergeben werden start n < 1 nein ja n = 1 z = 0 n ≠ 1 n gerade n = n / 2 nein n = 3*n + 1 z = z + 1 Ausgabe (n) Rückgabe(z) stop -4- ja Aufgabe 3 ( 4 + 3 + 4 = 11 Punkte ) a) Schreiben Sie eine Java-Methode, die für eine als Parameter gegebene ganze Zahl z die alterniernde Quersumme berechnet und zurückreicht. (alternierende Quersumme: Ist z = ±znzn-1...z1z0 mit den Dezimalziffern zi, so ist die n alternierende Quersumme aQS = z0-z1+z3-z4..... = ∑ (-1) z i i=0 Beispiel: z =12345 ⇒ aQS(z) = 5 – 4 + 3 – 2 + 1 = 3 int aQZ ( int z) { z = z < 0 ? –z : z; int s = 0, f = 1; while ( z > 0 ) { s += f*(z%10); f = - f; z = z / 10; } return s; } -5- i ) Aufgabe 3 ( Fortsetzung ) b) Die Zahlen Bk (k=1,2,...) werden durch folgende unendliche Reihen definiert: ∞ p 2k 22k-1 1 1 1 1 Bk =1+ 2k + 2k + 2k +...= ∑ 2k (2k)! 2 3 4 i=1 i Schreiben Sie eine Java-Methode zur näherungsweisen Berechnung dieser Zahlen entsprechend folgender Spezifikation: Name: Parameter: Rückgabewert: Wirkung: Hinweis: Bernouilli k (ganze Zahl) double-Zahl Die obige Reihe wird solange aufsummiert, bis sich der numerische Reihenwert nicht mehr ändert. Hieraus ergibt sich dann in offensichtlicher Weise die (Bernouilli-) Zahl Bk. Sie können beim Schreiben der Methode ohne Prüfung von k ≥1 ausgehen. double bernouilli (int k) { double s, sneu = 1, d, summand; long i = 2; // oder int i = 2; do { s = sneu; summand = 1; for (int j = 1; j <= 2*k; j++) // oder Math.pow(...) summand /=i; sneu += summand; i++; d = sneu - s; } while (d > 0); for (int j = 1; j <= 2*k; j++) s /= (Math.PI * 2); s = 2*s; for ( j = 2; j <= 2*k; i++) s *= j; return s; } -6- Aufgabe 3 ( Fortsetzung ) c) Um xn zu berechnen kann man folgenden rekursiven Ansatz verfolgen: n=0 1 xn = x n/2 * x n/2 n > 0, gerade n/2 n/2 x * x * x n ungerade Schreiben Sie eine Java-Methode, die als Eingabe x vom Typ double und n vom Typ int erhält und xn unter Benutzung obigen Ansatzes rekursiv ausrechnet. Dabei soll von n ≥ 0 ausgegangen werden. double power (double x, int n) { if (n == 0) return 1; double hilf = power (x, n/2); if (n % 2 == 0) return hilf * hilf; return hilf*hilf*x; } -7- Aufgabe 3 ( Fortsetzung ) d) Schreiben Sie eine Java-Methode für folgende Aufgabe: Eingabe: Drei int-Werte x, y und a; alle nicht negativ. Ausgabe: Ein Feld mit zwei nicht-negativen int-Werten i und j, so dass a = ix + jy, falls es solche Werte gibt, und ein leeres Feld sonst. int[] a3d (int x, int y, int a) { int[] f = null; for (int i = 0; i <= a; i++) for (int j = 0; j <= a; j++) if (i*x+j*y==a) { f = new int[2]; f[0] = i; f[1] = j; } return f; } -8- Aufgabe 4 ( 3 + 4 + 5 = 12 Punkte ) a) Die Methode ausgeben gibt die Komponenten des übergebenen eindimensionalen Feldes in einer Zeile aus. Was wird unter dieser Voraussetzung durch folgendes Programmstück ausgegeben? int[] vektor = {1, 2, 3}; int[][] matrix = {{4,5,6},{7,8,9},{10,11,12}}; System.out.print("Stelle 1: ");ausgeben(matrix[0]); matrix[1] = vektor; System.out.print("Stelle 2: ");ausgeben(matrix[1]); vektor[0] = 2; vektor [1] = 4; vektor [2] = 6; System.out.print("Stelle 3: ");ausgeben(matrix[1]); matrix[1][1] = 0; System.out.print("Stelle 4: ");ausgeben(vektor); matrix[0] = matrix[2]; matrix[2][2] = -1; System.out.print("Stelle 5: ");ausgeben(matrix[0]); System.out.print("Stelle 6: ");ausgeben(matrix[2]); vektor = matrix[0]; System.out.print("Stelle 7: ");ausgeben(vektor); Stelle 1: 4 5 6 Stelle 2:1 1 2 3 Stelle 3: 2 4 6 Stelle 4: 2 0 6 Stelle 5: 10 11 -1 Stelle 6: 10 11 -1 Stelle 7: 10 11 -1 -9- Aufgabe 4 (Fortsetzung) n b) Das Polynom p(x) = ∑ ai xi sei durch das Feld a=(a0,a1,...,an) mit reellen Komponenten i=0 ai gegeben. Schreiben Sie eine Java-Methode ableitung, die zu einem als Parameter in obiger Form n n i=0 i=1 gebenen Polynom p(x) = ∑ ai xi die das formale Ableitungspolynom p'(x) = ∑ i a i x i-1 berechnet und zurückreicht. double[] ableitung(double[] p) { double[] abl = new double[p.length-1); for (int i = 0; i < p.length-1; i++) abl[i] = (i+1)*p[i+1]; return abl; } - 10 - Aufgabe 4 (Fortsetzung) c) Schreiben Sie eine Java-Methode, die aus drei als Parameter übergebenen eindimensionalen reellen Feldern a, b und c mit n (Feld a) bzw. n-1 (Felder b und c) Komponenten die folgende (quadratische) Dreibandmatrix erzeugt: (i) In der Diagonalen stehen die ai (ii) In der oberen Nebendiagonalen stehen die bi (iii) In der unteren Nebendiagonalen stehen die ci (iv) Alle restlichen Matrixelemente sind = 0 1 Beispiel: a = ( 1,2,3,4), b = (5,6,7), c = (8,9,10) ⇒ 8 0 0 5 0 2 6 9 3 0 10 0 0 7 4 Hinweis: Sie können bei dieser Aufgabe ohne weitere Überprüfung voraussetzen, dass die Komponentenzahlen der drei Felder korrekt sind double[][] a4c (double[]a, double[] b, double[] c) { int dim = a.length; double erg = new double[dim][dim]; for (int i = 0; i < dim – 1; i++) { erg[i][i] = a[i]; erg[i+1][i] = c[i]; erg[i][i+1] = b[i]; } erg[dim-1][dim-1] = a[dim-1]; return erg; } - 11 - Aufgabe 4 (Fortsetzung) d) Eine quadratische Matrix a mit double-Einträgen soll auf Plausibilität überprüft werden. Dabei soll der Wert a[i][j] die Entfernung der Ortes mit der Nummer i zu dem Ort mit der Nummer j sein. Überprüft werden soll: • jeder Ort hat zu sich selbst die Entfernung 0.0, alle anderen Entfernungen sind > 0. • der Weg von einem Ort zu anderen ist genauso lang wie der Rückweg • Der direkte Weg von Ort i zu einem Ort j ist nie länger, als der Umweg über einen dritten Ort k; d.h. für alle i, j, k muss gelten: a[i][j] ≤ a[i][k] +a[k][j] Schreiben Sie eine Java-Methode, die als Eingabe a erhält und true oder false ausgibt, je nachdem, ob diese Bedingungen erfüllt sind oder nicht. boolean a4d (double[][] a) { int dim = a.length; for (int i = 0; i < dim; i++) for (int j = 0; j < dim; j++) for (int k = 0; k < dim; k++) if (a[i][j] > a[i][k]+a[k][j]) return false; return true; } - 12 - Aufgabe 5 a) ( 4 + 5 = 9 Punkte ) Betrachten Sie folgende Java-Methoden: public int a(int a) { System.out.println(a); if (a == 0) return 0; if (a%2==0) return c(b(a/2)); else return b(c(a)); } public int b (int b) { System.out.println(b); if (b == 0) return b; else return b(a(b/2)); } public int c (int c) { System.out.println(c); if (c == 0) return c; else return a(b(c/3)); } Was wird beim Aufruf a(10) ausgegeben? 10 5 2 1 0 0 0 0 0 - 13 - Aufgabe 5 ( Fortsetzung ) n b) Die Binomialkoeffizienten k n n 0 = n = 1; sind für 0 ≤ k ≤ n durch folgende Rekursionsvorschrift definiert: n n − 1 n − 1 k = k − 1 + k für 1 ≤ k ≤ n-1 Schreiben Sie eine rekursive Java-Methode zur Berechnung der Binomialkoeffizienten entsprechend folgender Spezifikation: Name: Parameter: Rückgabe: Hinweis: binomialKoeffizient n, k (ganze Zahlen) n Binomialkoeffizient , falls 0 ≤ k ≤ n; ansonsten 0 k Ihre Methode muss obige Rekursion zur Berechnung verwenden. int binomial (int n, int k) { if (k < 0 || n < k ) return 0; if (k== 0 || k == n ) return 1; return binomial(n-1,k-1)+binomial(n-1,k); } - 14 - Aufgabe 6 (4 + 2 = 6 Punkte ) a) Gehen Sie von folgender Klassendeklaration aus: public class A6a { public int a; private int b; public void setze_b(int c) { b = c;} } Kreuzen Sie in folgender Tabelle an, ob die jeweilige Anweisung erlaubt ist oder nicht (keine Begründung; Falschangaben führen zu Punktabzügen!). erlaubt public class UVW { void test1() { A6a A = new A6a(); A.a = 1; A.b = 1; A.setze_b(1); } } public class XYZ extends A6a { void test2() { A6a B = new A6a(); B.a = 1; B.b = 1; a = 1; b = 1; setze_b(1); } } - 15 - nicht erlaubt Aufgabe 6 (Fortsetzung) b) Folgende korrekte Java-Klassen seien vorgegeben: public abstract class A6b { private String name; protected int x, y; public abstract int f(); public abstract boolean f(int a); private String getName(){ return name;} } public class XYZ extends A6b { protected int a, b; public XYZ(int x, int y, int aa, int bb) { this.x = x; this.y = y; a = aa; b = bb; } public int f() { return a + b; } public boolean f(int a) { return this.f() == a; } } Kreuzen Sie jeweils an, ob die folgenden Anweisungen bzw. Anweisungsfolgen insgesamt legal oder illegal sind. Falsche Angaben führen zu Punktabzug. Falls sie legal sind, geben Sie auch den Wert des angegebenen Ausdrucks A.f() bzw. B.f() nach Ausführung der jeweiligen Anweisungen an. i) A6b A = new XYZ(1, 2, 3, 4); illegal ii) A6b A; XYZ B = new XYZ (1, 2, 3, 4); A = B; illegal iii) legal, A.f() = A6b A; XYZ B = new B(1, 2, 3, 4); B = A; illegal iv) legal, A.f() = legal, B.f() = XYZ B = new XYZ (1, 2, 3, 4); String n = B.getName(); illegal legal, B.f() = - 16 - Aufgabe 7 (7 + 4 + 5 = 16 Punkte ) a) Entwerfen Sie eine Java-Klasse Lastentransporter entsprechend folgender Spezifikation (auf die Attribute soll nur mit Methoden der Klasse, auf die Methoden von überall her zugegriffen werden können): Attribute: − gesamtGewicht (ganze Zahl, zulässiges Gesamtgewicht) − leerGewicht (ganze Zahl) − ladung (ganze Zahl, Gewicht der Ladung) Konstruktor: − Parameter: zwei ganze Zahlen für zulässiges Gesamtgewicht und Leergewicht − Wirkung: Der Konstruktor setzt dieAttribute entsprechend den übergebenen Parametern; der Lastentransporter hat noch keine Ladung. Dabei ist zu beachten: - Das zulässige Gesamtgewicht ist ≥ 2000 und ≤ 20000 - Das Leergewicht ist ≥ 500 und ≤ zulässiges Gesamtgewicht.. Liegt ein Parameter außerhalb der angegebenen Grenzen, so wird er durch die nächstgelegene Grenze ersetzt. Methoden: − zeigen - Parameter: - Rückgabewert: - Wirkung: − laden - Parameter: - Rückgabewert: - Wirkung: Alle Daten werden auf dem Bildschirm anzeigt wieviel (ganze Zahl) ganze Zahl die aktuelle Ladung wird um wieviel geändert (d.h. erhöht bzw. erniedrigt), aber maximal bis zum zulässigen Gesamtgewicht und minimal bis zu 0. Der Rückgabewert ist die tatsächlich erfolgte Änderung der Ladung. - 17 - Aufgabe 7 ( Fortsetzung ) class Lastentransporter { private int gesamtGewicht, leerGewicht, ladung; Lastentransporter (int gw, int lw) { if (gw < 2000) gw = 2000; if (gw > 20000) gw = 20000; if (lw < 500) lw = 500; if (lw > gw ) lw = gw; gesamtGewicht = gw; leerGewicht = lw; ladung = 0; } public void zeigen() { System.out.println("zul. Gesamtgew.: "+gesamtGewicht+ "\nLeerGewicht: " + leerGewicht+ "\nLadung: "+ladung); } public int laden (int wieviel) { if (wieviel >= 0) { if (ladung + leerGewicht + wieviel <= gesamtGewicht) { ladung += wieviel; return wieviel; } int aktwieviel = gesamtGewicht – leerGewicht - ladung; ladung = gesamtGewicht – leerGewicht; return aktwieviel; } if (wieviel <= ladung) { ladung -= wieviel; return wieviel; } wieviel = ladung; ladung = 0; return ladung; } } - 18 - Aufgabe 7 ( Fortsetzung ) b) Erweitern Sie die Klasse Lastentransporter zu einer Klasse LKW entsprechend folgender Spezifikation: zusätzliche Attribute: − Motorleistung (ganze Zahl) − anhaengenErlaubt (true/false) − Anhaenger (Lastentransporter) Konstruktor: − Parameter: wie bei Lastentransporter; zusätzlich zwei Parameter für beiden zusätzlichen Attribute Motorleistung und anhaengenErlaubt. − Wirkung: Wie bei Lastentransporter; zusätzlich werden die Motorleistung und anhaengenErlaubt entsprechend den übergebenen Parametern gesetzt. Dabei ist zu beachten, dass die Motorleistung mindestens 100 und maximal 800 ist. Das Attribut Anhaenger wird mit null initialisiert (d.h. es ist noch kein Anhänger da). Methoden: − zeigen - Parameter: - Rückgabewert: - Wirkung: − anhaengen - Parameter: - Rückgabewert: - Wirkung: Alle Daten werden auf dem Bildschirm anzeigt Haenger (Lastentransporter) true/false Hat der LKW noch keinen Anhänger (d.h. Anhaenger == null) und ist das Anhängen erlaubt, so wird der Haenger angehängt. Im Rückgabewert wird angezeigt, ob das Anhängen erfolgreich war. − laden - Parameter: wieviel (ganze Zahl) - Rückgabewert: ganze Zahl (tatsächlich erfolgte Änderung der Ladung) - Wirkung: die aktuelle Ladung wird um wieviel geändert (d.h. erhöht oder erniedrigt), aber maximal bis zum zulässigen Gesamtgewicht und minimal bis zu 0. Dabei ist zu beachten: Beim Beladen (d.h. wieviel > 0) werden zunächst der eigentliche LKW bis zum zulässigen Gesamtgewicht und dann der Anhänger mit dem verbleibenden Rest beladen. Beim Entladen (wieviel < 0) wird zunächst der Anhänger entladen und dann der eigentliche LKW. - 19 - Aufgabe 7 ( Fortsetzung ) class LKW extends Lastentransporter { private boolean anhaengererlaubt; private Lastentransporter Anhaenger; LKW(int gw, int lw, boolean ok) { super(gw,lw); anhaengererlaubt = ok; Anhaenger = null; } public void zeigen() { super.zeigen(); if (anhaengererlaubt){ System.out.println("Anhaenger ist erlaubt"); if (Anhaenger != null){ System.out.println("Anhaenger ist vorhanden"); Anhaenger.zeigen(); } } else System.out.println("Anhaenger ist nicht erlaubt"); } public boolean anhaengen(Lastentransporter H) { if (anhaengererlaubt && Anhaenger == null) { Anhaenger = H; return true; } return false; } public int laden ( int wieviel ) { int hilf1 = super.laden(wieviel) // der LKW int rest = wieviel – hilf1; int hilf2 = 0; if (Anhaenger != null && rest != null) hilf2 = Anhaenger.laden(rest); return hilf1+hilf2; } } - 20 - Aufgabe 7 ( Fortsetzung ) c) Entwerfen Sie eine Klasse Spedition entsprechend folgender Spezifikation: Attribute: − Name (String) − Fuhrpark (eindimensionales Feld zum Speichern der LKWs) − aktAnzahl (aktuelle Anzahl der LKWs im Fuhrpark) Konstruktor: − Parameter: Firmenname maximale Anzahl der LKWs − Wirkung: Der Konstruktor setzt den Firmennamen und deklariert das Feld Fuhrpark in der durch den zweiten Parameter gegebenen Größe. Wird als maximale Zahl der LKWs eine Zahl < 1 übergeben, so ist diese durch 1 zu ersetzen. Die aktuelle Anzahl der LKWs wird mit 0 initialisiert. Methoden: − zeige Parameter: Rückgabewert: Wirkung: Der Firmenname, die Anzahl der LKWs und deren Daten werden auf dem Bildschirm angezeigt. − kaufen Parameter: Auto (LKW) Rückgabewert: true / false Wirkung: Falls im Fuhrpark noch Platz ist, wird der übergebene LKW dem Fuhrpark hinzugefügt. - 21 - Aufgabe 7 ( Fortsetzung ) class Spedition { private String Name; private LKW[] Fuhrpark; private int aktanzahl; Spedition(String N; int max) { Name = N; max = (max < 1) ? 1 : max; Fuhrpark = new LKW[max]; aktanzahl = 0; } public void zeigen() { System.out.println("Firma: "+ Name + "\nAnzahl der LKW: "+ aktanzahl); for (int i = 0; i < aktanzahl; i++) Fuhrpark[i].zeigen(); } public boolean kaufen(LKW A) { if (aktanzahl < Fuhrpark.length) { Fuhrpark[aktanzahl] = A; aktanzahl++; return true; } return false; } } - 22 - Zusatzblatt - 23 -