Programmierung 1 (Wintersemester 2015/16) Aufgaben für die

Werbung
Fachrichtung 6.2 — Informatik
Universität des Saarlandes
Tutorenteam der Vorlesung Programmierung 1
Programmierung 1 (Wintersemester 2015/16)
Aufgaben für die Übungsgruppen: 14
(Kapitel 15 & 16)
Hinweis: Dieses Übungsblatt enthält von den Tutoren für die Übungsgruppe erstellte Aufgaben.
Die Aufgaben und die damit abgedeckten Themenbereiche sind für die Klausur weder relevant noch irrelevant.
Reihungen
Aufgabe 14.1
Schreiben Sie eine Prozedur swapPairwise: α array → unit, die in einer gegebenen Reihung die Komponenten
vorne beginnend paarweise tauscht. Beispielsweise soll die Reihung [2, 3, 4, 5] durch diese Prozedur zu
[3, 2, 5, 4] vertauscht werden. Bei einer ungeraden Anzahl an Komponenten darf die letzte Komponente
unverändert bleiben.
Aufgabe 14.2 (Sortieren durch Auswählen)
Ein einfacher, als Sortieren durch Auswählen bezeichneter, Algorithmus geht beim Sortieren einer durch ihre
linkeste und rechteste Position gegebenen nicht leeren Teilreihung (l, r) wie folgt vor:
• Bestimme die Position m einer Komponente minimaler Größe.
• Vertausche die Komponenten an den Positionen l und m.
• Sortiere die Teilreihung (l + 1, r).
Schreiben Sie eine Prozedur ssort: int array → unit, die Reihungen durch Auswählen sortiert. Bestimmen
Sie die Laufzeit Ihrer Prozedur.
Imperative Schlangen
Aufgabe 14.3
Erweitern Sie imperative Schlangen um
(a) eine Operation add: α queue → α → unit, die ein Element in konstanter Laufzeit vorn an eine Schlange
anfügt.
(b) eine Operation delete: α queue → unit, die das letzte Element einer Schlange in linearer Laufzeit
entfernt. Wenn nötig, werfen Sie Empty.
Aufgabe 14.4
Ergänzen Sie die Signatur und Implementierung der imperativen Schlangen aus dem Buch (S. 312) um eine
Prozedur insertPosition: α queue → α → int → unit, die, gegeben eine Schlange, einen Wert x und
eine Zahl n, einen neuen Eintrag mit Inhalt x an die n-te Position der Schlange einfügt. Für Position 0, soll das
Element als Kopf der Schlange eingefügt werden, für Position 1 als zweites Element usw. Sollte die übergebene
Position die Länge der Schlange überschreiten, soll der Eintrag wie gewohnt an das Ende der Schlange angefügt
werden.
Hinweis: Überlegen Sie sich zunächst eine sinnvolle Hilfsprozedur, die Sie innerhalb der Struktur deklarieren.
Diese Prozedur soll es Ihnen ermöglichen, einen neuen Eintrag zwischen zwei bereits existierenden Einträgen der
Schlange einzufügen.
1
Schleifen
Aufgabe 14.5 (Kleine Gemeinheit)
Was tut das folgende Programm?
let
val i = 0
val n = 1
val _ = while ( i < 10) do ( i = n + 1; n = n * i )
in n end
Aufgabe 14.6
Nutzen Sie im Folgenden while-Schleifen. Verzichten Sie auf Rekursion.
(a) Schreiben Sie eine Prozedur gauss: int → int, die die Summe aller Zahlen von 0 bis zu einer Eingabe n
berechnet.
(b) Schreiben Sie eine Prozedur fib: int → int, die die n-te Fibonacci-Zahl berechnet.
(c) Schreiben Sie eine Prozedur prim: int → bool, die prüft, ob eine Eingabe n eine Primzahl ist.
(d) Schreiben Sie eine Prozedur sum: int list → int, die die Zahlen einer Liste von Zahlen aufaddiert.
(e) Schreiben Sie eine Prozedur foldli: (α * β → β) → β → α list → β, die Faltung von links implementiert.
Aufgabe 14.7
Betrachten Sie die folgenden Prozeduren. Geben Sie semantisch äquivalente Prozeduren an, die nicht rekursiv
sind, sondern Schleifen benutzen.
Hinweis: Stellen Sie zuerst sicher, dass die Prozedur endrekursiv ist.
(a) fun pot 0 x a = a
| pot n x a = pot ( n − 1) x ( a * x )
(b) fun square 0 = 0
| square n = square ( n − 1) + 2 * n − 1
(c) fun mystery n a b c d = if n + b + d < 0 then ( b + c ) * a
else mystery ( n − 1) b a ( c * d ) ( d − a )
Aufgabe 14.8 (Reverse)
Schreiben Sie eine Prozedur reverse: int array → unit, die eine Reihung mithilfe einer Schleife durch
Umordnung Ihrer Komponenten reversiert.
Halde/Linearer Speicher
Aufgabe 14.9
Geben Sie die Werte aller allozierten Zellen an. Sie können dies (wie die Prozedur show) als Liste darstellen oder
alternativ die verzeigerte Blockdarstellung benutzen.
(a) val
val
val
val
a
_
_
b
=
=
=
=
new 10
update a 0 1
update a 1 1
iter 8 2 ( fn i ⇒ ( update a i ( sub a ( i−1) + sub a ( i−2)); i+1))
(b) val
val
val
val
val
a
_
_
_
_
=
=
=
=
=
new 4
update
update
update
update
a
a
a
a
0
1
2
3
( a+2)
( a+0)
( a+3)
( a+1)
2
Aufgabe 14.10
Im Folgenden sollen Operationen auf der Halde (Buch S. 314) betrachtet werden.
(a) Schreiben Sie eine Prozedur put: int → int → unit, die eine Zahl an eine Adresse schreibt.
(b) Schreiben Sie eine Prozedur putints: int → int list → unit, die eine Folge von Zahlen hintereinander in die Halde schreibt.
(c) Schreiben Sie eine Prozedur rev: int → int, die eine Liste reversiert. Sei dazu die Prozedur
append: int → int → int, die zwei Listen konkateniert, gegeben.
(d) Schreiben Sie eine Prozedur counter: unit → int, die in einer einzigen Speicherzelle einen Zähler
implementiert, die beim n-ten Aufruf die Zahl n liefert. Die Halde sei leer.
Aufgabe 14.11 (Lineare Darstellung von Listen)
Sie haben in Kapitel 15.10 eine Möglichkeit kennen gelernt, Listen von Zahlen in einer Halde darzustellen. Auf
diese können Sie die schon bekannten Prozeduren auf Listen aus Kapitel 4 anwenden. Allozieren Sie außer für
tabulate keinen neuen Speicherplatz, wenn dies nicht unbedingt notwendig ist.
(a) Schreiben Sie eine Prozedur length: address → int, die zu einer angegebenen Adresse die Länge der
angegebenen verketteten Liste bestimmt.
(b) Schreiben Sie eine Prozedur map: address → (int → int) → address, die auf die Liste einer angegebenen Adresse die Prozedur map anwendet.
(c) Schreiben Sie eine Prozedur exists: address → (int → bool) → bool, die auf die Liste einer angegebenen Adresse die Prozedur exists anwendet.
(d) Schreiben Sie eine Prozedur all: address → (int → bool) → bool, die auf die Liste einer angegebenen Adresse die Prozedur all anwendet.
(e) Schreiben Sie eine Prozedur filter: address → (int → bool) → address, die auf die Liste einer
angegebenen Adresse die Prozedur filter anwendet.
Tipp: Sie benötigen eine Hilfsprozedur, um sich das letzte gültige Argument merken zu können.
(f) Schreiben Sie eine Prozedur tabulate: int * (int → int) → address, die für eine Zahl n die Prozedur
tabulate anwendet.
(g) Schreiben Sie eine Prozedur rev: address → address, die die Liste einer Adresse reversiert.
Stapelmaschinen
Aufgabe 14.12
Geben Sie an, wie sich der Stapel bei der Ausführung der folgenden Programme schrittweise entwickelt.
Zum Beispiel soll zu [con 1, con 2, sub, halt] die Entwicklung [ ] → [1] → [1, 2] → [1] angegeben werden.
(a) [con 1, con 2, getS 0, getS 1, add, putS 0, halt]
(b) [con 3, con 4, con 5, con 6, getS 3, getS 2, add, getS 1, getS 0, sub, halt]
Aufgabe 14.13
Schreiben Sie Maschinenprogramme, die die folgenden Ausdrücke auswerten:
(a) 20 + 7 − 3
(b) 20 + (7 − 3)
(c) 1 + (2 + 3) ∗ (4 − 5)
(d) if 2 ∗ 3 ≤ 12 − 3 then 3 else 5
(e) if (2 + 5) ≤ (1 ∗ 7) then (3 + 2) else (2 + 1) ∗ (3 + 4)
3
Aufgabe 14.14
(a) Schreiben Sie ein Programm, das zu einer natürlichen Zahl n mit einer Schleife die Fakultät n! berechnet.
Schreiben Sie das Programm zuerst in SML und dann in M (dazu nehmen wir an, dass die Zahl n an
der Position 0 auf dem Stapel liegt). Achten Sie darauf, dass Ihr Programm nur die Fakultät im Stapel
zurücklässt.
(b) Schreiben Sie ein Programm, das zu einer natürlichen Zahl n mit einer Schleife die Gauß-Summe für n
berechnet.
Aufgabe 14.15
Übersetzen Sie das folgende W -Programm in M :
var n
var res := 1
while 1 <= n do
res := res * n
n := n − 1
end
Aufgabe 14.16
Scheiben Sie ein Programm (in W und M), das zu n die Liste [n, ..., 0] berechnet.
Aufgabe 14.17
Schreiben Sie ein Maschinenprogramm, dass die Länge einer Liste berechnet. Halten Sie sich dabei an folgende
Skizze in W:
var xs
var n := 0
while 0 <= xs do
n := n + 1
xs := xs .1
end
return n
xs.1 liefert den Wert in der zweiten Zelle des Blocks, dessen Adresse der Wert der Variablen xs ist.
Aufgabe 14.18 (Eigene Prozeduren aufrufen)
Schreiben Sie ein Programm in M, welches mithilfe einer Prozedur, die das Minimum zweier Zahlen berechnet,
den Ausdruck min(17, 8) − min(5, 7) berechnet.
Aufgabe 14.19
Übersetzen Sie die folgende Prozedur nach M:
fun fac n = if n < 2 then 1 else fac ( n − 1) * n
Nehmen Sie dabei an, dass die Befehlssequenz für die Prozedur im Programmspeicher mit der Adresse 0 beginnt.
Aufgabe 14.20
Übersetzen Sie die folgende Prozedur nach M:
fun fib n = if n < 2 then n else fib ( n − 2) + fib ( n − 1)
Aufgabe 14.21 (Rätsel)
Was tut das folgende Programm? Das Programm erwartet, dass zwei Argumente auf dem Stack liegen, bevor es
ausgeführt wird.
[( getS 0) , ( con 1) , ( getS 1) , leq , ( cbranch 2) , ( branch 8) ,
( getS 0) , mul , ( con 1) , ( getS 1) , sub , ( putS 1) , ( branch ∼11) , halt ]
4
Herunterladen