Programmiertechnik II Klausur WS 2016/17 Angewandte Informatik

Werbung
Programmiertechnik II
Klausur WS 2016/17
Angewandte Informatik Bachelor
Name
Matrikelnummer
Aufgabe
Punkte
Aufgabe
Punkte
1
4
6
18
2
12
7
18
3
12
8
12
4
12
9
12
5
20
Summe
120
Zwischensumme
60
Note
Prof. Dr. O. Bittel, HTWG Konstanz
WS 2016/17
1/12
Aufgabe 1
(4 Punkte)
Beschreiben Sie mit einem Speicherbelegungsbild, was durch die folgende main-Funktion geleistet
wird:
class Point {
private int x;
private int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public static void main(String[] a) {
Point[] p = new Point[3];
p[0] = new Point(1,2);
p[1] = p[0];
}
}
Prof. Dr. O. Bittel, HTWG Konstanz
WS 2016/17
2/12
Aufgabe 2
(12 Punkte)
Für die Knoten einer linear verketteten Liste ist folgende Klasse definiert:
class Node {
int data;
Node next;
// Referenz auf nächsten Knoten
Node(int x, Node n) {data = x; next = n;}
}
Gegeben ist folgendes Speicherbelegungsbild. a ist ein Feld (grau unterlegter Speicherplatz) von
linear verketteten Listen.
a) Schreiben Sie genau eine Java-Anweisung, die den Typ von a definiert und den grau unterlegten
Speicherplatz anlegt.
Node[] a = new Node[3];
b) Schreiben Sie eine Folge von Java-Anweisungen (keine Schleife!), die die im Speicherbelegungsbild gezeigte Datenstruktur aufbaut. Die Java.Anweisung aus a) kann vorausgesetzt werden.
a[0]
a[0]
a[0]
a[2]
=
=
=
=
new
new
new
new
Node(7,
Node(3,
Node(5,
Node(1,
null);
a[0]);
a[0]);
null);
c) Schreiben Sie mit Hilfe von Schleifen ein Programmstück, das alle Daten der abgebildeten
Datenstruktur ausgibt.
for (Node p : a)
for (Node q = p; q != null; q = q.next)
println(q.data);
Prof. Dr. O. Bittel, HTWG Konstanz
WS 2016/17
3/12
Aufgabe 3
(12 Punkte)
java.util.Arrays bietet u.a. die Methode
static boolean equals(Object[] a, Object[] b)
mit folgender Spezifikation an:
This method returns true if the two specified arrays of Objects are equal to one another. The two
arrays are considered equal if both arrays contain the same number of elements, and all
corresponding pairs of elements in the two arrays are equal. Two objects e1 and e2 are
considered equal if (e1==null ? e2==null : e1.equals(e2)). In other words, the two arrays are
equal if they contain the same elements in the same order. Also, two array references are
considered equal if both are null.
a) Was bedeutet Kovarianz von Feldern?
Falls A <: B, dann ist A[ ] <: B[ ].
b) Welche Parameter dürfen beim Aufruf von equals übergeben werden?
a und b dürfen beliebige Felder sein.
c) Was gibt folgendes Programm auf die Konsole aus?
Integer[] a = new Integer[]{1, 2};
Double[] b = new Double[]{1.0, 2.0};
Object[] c = new Integer[]{1, 2};
System.out.println(a.equals(c));
System.out.println(Arrays.equals(a,b));
System.out.println(a == c);
System.out.println(Arrays.equals(a,c));
Prof. Dr. O. Bittel, HTWG Konstanz
WS 2016/17
//
//
//
//
false
false
false
true
4/12
Aufgabe 4
QuickSort mit 3-Median-Strategie (12 Punkte)
Das 11-elementige Feld a = {5, 15, 2, 17, 2, 1, 3, 7, 4, 6, 10} wird mit Quicksort mit 3-MedianStrategie sortiert. Außerdem ist Quicksort so modifiziert, dass Teilfelder mit genau 2 Elementen mit
einem einfachen Vertauschungsschritt sortiert werden.
Beschreiben Sie, wie sich das Feld a beim Sortieren ändert. Benutzen Sie eine tabellenartige
Darstellung wie in der Vorlesung. Geben Sie außerdem die Aufrufstruktur von Quicksort an.
5 15 2
10
4
3
17 2
3
2
1
1
2
3
2
2
1
2
2
4
3
3
3
4
17
5
5 15 7
17
6
6
6
Prof. Dr. O. Bittel, HTWG Konstanz
7
4
6
10
5
15
4
2
3
10
1
4
1
10 6
17
17
15
17
15 17
7 10 15 17
10 7
7 10
7 10
WS 2016/17
5/12
Aufgabe 5
Linear verkettete Liste (20 Punkte)
Eine soll eine Klasse für linear verkette Listen realisiert werden, wobei eine Referenz auf den Anfang
begin und eine Referenz auf das Ende end der Liste gespeichert wird. Die Knoten sollen Strings
als Daten enthalten.
Lösen Sie folgende Aufgaben. Die geforderten Methoden können direkt in die Klassendefinition auf
der nächsten Seite geschrieben werden. Achten Sie dabei auf Sonderfälle.
a) addFront(s) fügt den String s am vorderen Ende der Liste ein.
b) removeFront() löscht das Element am vorderen Ende der Liste und liefert true bei Erfolg
zurück.
c) add(s) fügt den String s am hinteren Ende der Liste ein. Die Methode muß eine Laufzeit von
O(1) haben.
d) remove() löscht das Element am hinteren Ende der Liste und liefert true bei Erfolg zurück.
e) addAll(l) fügt die Liste l am hinteren Ende der Liste ein.
f) Wie muß die Methode add verändert werden, so dass verkettete Aufrufe möglich sind?
l.add("dies").add("ist").add("ein").add("Test");
public List add(String w) {
// Code wie bei alter Methode add:
// ...
return this;
}
Prof. Dr. O. Bittel, HTWG Konstanz
WS 2016/17
6/12
public class List {
static private class Node {
private String str;
private Node next;
private Node(Node p, String s) {this.str = s; this.next = p;}
}
private Node begin, end;
public List() {
begin = end = null;
}
public void addFront(String s) {
if (begin == null)
begin = end = new Node(null, s);
else
begin = new Node(begin, s);
}
public boolean removeFront() {
if (begin == null)
return false;
begin = begin.next;
if (begin == null)
end = null;
return true;
}
public void add(String s) {
if (begin == null)
begin = end = new Node(null, s);
else {
end.next = new Node(null, s);
end = end.next;
}
}
public boolean remove() {
if (begin == null) return false;
if (begin == end) {
begin = end = null;
return true;
}
Node p = begin;
while (p.next != end) p = p.next;
p.next = null;
end = p;
return true;
}
public void addAll(List l) {
for (Node p = l. begin; p!= null; p = p.next)
add(p.str);
}
Prof. Dr. O. Bittel, HTWG Konstanz
WS 2016/17
7/12
Aufgabe 6
Bäume (18 Punkte)
Die Klasse Tree auf der folgenden Seite realisiert Bäume mit int-Daten in jedem Knoten und einer
beliebigen Anzahl von Kindern. root ist die Wurzel des Baums.
In der Abbildung (a) und (b) sind zwei Beispielbäume gezeigt.
Ergänzen Sie die Klassendefinition um folgende Methoden:
a) Schreiben Sie eine Methode build, die den in (b) gezeigten Baum aufbaut.
b) Die Methode sum gibt die Summe aller Integerzahlen im Baum zurück. Beim in (a) abgebildeten
Baum ist die Summe 31. sum ruft die private Methode sumR auf, die den Baum rekursiv
durchläuft. Schreiben Sie die Methode sumR.
c) Die Methode collect gibt die Liste aller Integerzahlen im Baum zurück. collect ruft die
private Methode collectR auf, die den Baum rekursiv durchläuft und alle Zahlen aufsammelt.
Schreiben Sie die Methode collectR.
d) Welche Liste gibt Ihre Methode collect für den in (a) gezeigten Baum zurück?
1, 6, 2, 3, 1, 3, 4, 1, 2, 2, 1, 5
Prof. Dr. O. Bittel, HTWG Konstanz
WS 2016/17
8/12
class Tree {
private static class Node {
int data;
List<Node> children;
Node(int d) {
data = d;
children = new LinkedList<>();
}
}
private Node root;
public void build() {
root = new Node(5);
root.children.add(new Node(1));
root.children.add(new Node(2));
}
public int sum() {
if (root == null)
return 0;
else
return sumR(root);
}
private int sumR(Node p) {
int s = p.data;
for (Node q : p.children) {
s += sumR(q);
}
return s;
}
public List<Integer> collect() {
List<Integer> l = new LinkedList<>();
collectR(root, l);
return l;
}
private void collectR(Node p, List<Integer> l) {
for (Node q : p.children) {
collectR(q, l);
}
l.add(p.data);
}
}
Prof. Dr. O. Bittel, HTWG Konstanz
WS 2016/17
9/12
Aufgabe 7
Java-Collections (18 Punkte)
Die Klasse RaumVerwaltung verwaltet Räume und die darin stattfindenden Lehrveranstaltungen.
Die Klasse verwendet dazu eine Map, die jedem Raum eine Menge der darin stattfindenden Lehrveranstaltungen zuordnet. Räume und Lehrveranstaltungen werden über ihren Namen vom Typ
String identifiziert.
a) Schreiben Sie eine Methode insert(r,lv), die in der Raumverwaltung speichert, dass die
Lehrveranstaltung lv im Raum r stattfindet. Falls der Raum noch nicht existiert, dann muss er
neu angelegt werden.
b) Schreiben Sie eine Methode getLVen(r), die für den Raum r alle in ihm stattfindenden
Lehrveranstaltungen zurückliefert. Achten Sie darauf, dass Ihre Methode die gewünschten Daten
„direkt“ (d.h. ohne Schleife) aus der Map abliest.
c) Schreiben Sie eine Methode getRaeume(lv), die für die Lehrveranstaltung lv alle Räume
zurückliefert, in der lv stattfindet. Hinweis: hierfür ist eine Schleife notwendig.
d) Schätzen Sie die Laufzeiten der Methoden getLVen und getRaueme mit Hilfe der O-Notation
ab. Gehen Sie davon aus, dass die Raumverwaltung n Räume und m Lehrveranstaltungen enthält
und führen Sie eine Worst-Case-Betrachtung durch.
getLVen: T(n,m) = O(log(n)).
getRaueme: T(n,m) = O(n (log(n) + log(m))).
class RaumVerwaltung {
private Map<String, Set<String>> meineLVen = new TreeMap<>();
public void insert(String raum, String lv) {
if (!meineLVen.containsKey(raum))
meineLVen.put(raum, new TreeSet<>());
meineLVen.get(raum).add(lv);
}
public Set<String> getLVen(String raum) {
return meineLVen.get(raum);
}
public Set<String> getRaeume(String lv) {
Set<String> meineRaeume = new TreeSet<>();
for (Map.Entry<String, Set<String>>
entry : meineLVen.entrySet()) {
if (entry.getValue().contains(lv))
meineRaeume.add(entry.getKey());
}
return meineRaeume;
}
}
Prof. Dr. O. Bittel, HTWG Konstanz
WS 2016/17
10/12
Aufgabe 8
Subtyping (12 Punkte)
Es werden folgende Variablen definiert, wobei die Initialisierungen weggelassen sind.
Collection<Double> colDb;
Collection<Number> colNb;
Collection<Integer> colInt;
Collection<Object> colObj;
List<String> listStr;
Set<Integer> setInt;
List<Object> listObj;
a) Geben Sie in folgender Tabelle für jeden Aufruf an, ob er korrekt ist („+“) oder ob er nicht
korrekt ist („-“). Falsche Antworten geben Abzüge!
listStr.containsAll(colNb);
colInt.addAll(colNb);
listStr.removeAll(colObj);
colNb.addAll(setInt);
listObj.add(colInt);
setInt.addAll(colInt);
colDb.containsAll(setInt);
listObj.addAll(colDb);
colDb.addAll(setInt);
+
+
+
+
+
+
+
-
b) Die statische Methode copy kopiert die Liste src in die Liste dest.
static <T> void copy(List<? super T> dest, List<? extends T> src)
Geben Sie in folgender Tabelle für jeden Aufruf an, ob er korrekt ist („+“) oder ob er nicht
korrekt ist („-“). Falsche Antworten geben Abzüge!
Collections.copy(listStr, listObj);
Collections.copy(colObj, listObj);
Collections.copy(listObj, listStr);
Prof. Dr. O. Bittel, HTWG Konstanz
+
WS 2016/17
11/12
Aufgabe 9
Java 8 (12 Punkte)
Gegeben sind folgende Interfaces aus der Java-API (Schnittstellen sind leicht vereinfacht):
Funktionales Interface
Abstrakte bzw. default-Methode
Beschreibung
Predicate<T>
boolean test(T t)
Predicate<T> and( Predicate<T> p)
Predicate<T> or( Predicate<T> p)
Predicate<T> p negate()
1-stelliges Prädikat
logisches Und
logisches Oder
logische Negation
BiPredicate<T, U>
boolean test(T t, U u)
2-stelliges Prädikat
UnaryOperator<T>
T apply(T t)
1-stelliger Operator vom Typ T → T
BinaryOperator<T>
T apply(T t, T u)
2-stelliger Operator vom Typ T × T → T
Interface
Default-Methode
Beschreibung
Collection<T>
boolean removeIf( Predicate<T> p )
Entfernt aus der Collection jedes Element x,
für das p(x) zutrifft.
List<T>
void replaceAll(UnaryOperator<E> f)
Ersetzt in der Liste jedes Element x durch f(x).
a) Gegeben ist eine Lambda-Funktion ggT, die den größten gemeinsamen Teiler zweier ganzer
Zahlen bestimmt. Definieren Sie mit Hilfe von ggT ein zweistelliges Prädikat
istTeilerFremd, das prüft, ob zwei ganze Zahlen teilerfremd sind. Zwei Zahlen sind
teilerfremd, wenn sie außer 1 keinen gemeinsamen Teiler haben.
BinaryOperator<Integer> ggT = ...;
BiPredicate<Integer, Integer> istTeilerFremd = (n, m) -> ggT.apply(n,m) == 1;
b) Schreiben Sie einen replaceAll-Aufruf, der jede gerade Zahl in der Liste intList quadriert.
List<Integer> intList = Arrays.asList(5, 4, 3, 8, 6, 9);
intList.replaceAll(n -> n%2 == 0 ? n*n : n);
c) Schreiben Sie einen removeIf-Aufruf, der in einer String-Liste strList alle Strings mit
kleinem Anfangsbuchstaben löscht. Hinweis: charAt(int i) liefert das i-te Zeichen in einem
String.
List<String> strList = new LinkedList<>(Arrays.asList("auch", "ein", "Test"));
strList.removeIf(s -> 'a' <= s.charAt(0) && s.charAt(0) <= 'z');
d) Gegeben ist ein einstelliges Prädikat isNotPrime, das prüft ob eine Zahl keine Primzahl ist.
Definieren Sie mit Hilfe der logisches Operationen aus Predicate ein 1-stelliges Prädikat
myPred, das prüft, ob eine Zahl eine Primzahl und größer oder gleich 100 ist.
Predicate<Integer> isNotPrime = ...;
Predicate<Integer> myPred = isNotPrime.negate().and(n -> n>= 100);
Prof. Dr. O. Bittel, HTWG Konstanz
WS 2016/17
12/12
Herunterladen