Projektaufgaben zur C–Programmierung im WS07/08

Werbung
Prof. Dr. K.–U. Jahn
HTWK Leipzig, Fb IMN
Projektaufgaben zur C–Programmierung im WS07/08
Verwenden Sie in den Programmen die in den jeweiligen Aufgaben genannten Bezeichnungen!
Für weitere eventuell verwendete Variablen ist deren Verwendungszweck zu kommentieren!
Die Programme sind klar zu gliedern und ausreichend mit Kommentaren zu versehen!
(Projektaufgabe 5 wird in den Praktika gemeinsam bearbeitet.)
Projektaufgabe 1:
Lexikographisches Sortieren von Zeichenketten über einem vorgegebenen Alphabet
Es sei n die Anzahl der Elemente eines Alphabetes A von druckbaren ASCII–Zeichen,
1 ≤ n ≤ 95. Der Wert von n ist während der Laufzeit zu erfragen.
Nachdem der Wert von n bekannt ist, soll ein dynamisches Array a der Länge n mit
Elementen vom Typ char erzeugt werden. In dieses sind nach entsprechenden Eingabeaufforderungen n druckbare ASCII–Zeichen von der Tastatur her einzutragen, wobei durch
die Eingabereihenfolge eine lineare Ordnung in A definiert werde (das zuerst eingegebene
Zeichen werde wie das kleinste Element des künstlichen Alphabets A behandelt usw.).
Das Programm soll es nicht zulassen, dass ein Zeichen doppelt eingegeben wird.
Nachdem auf diese Weise das Alphabet zusammen mit einer Ordnungsrelation bekannt
ist, sollen die Anzahl k von Zeichenketten sowie deren maximale Länge m erfragt und
von der Tastatur her eingegeben werden (1 ≤ k, m). Der Computer soll dann ein dynamisches Array z der Länge k mit unterschiedlich langen (jeweils zufällige Länge) nichtleeren
zufälligen Zeichenketten maximaler Länge m erzeugen, wobei die Zeichen nur aus dem
Alphabet A sein dürfen. Die k Zeichenketten sind dann, jeweils beginnend mit einer neuen Zeile, in der durch z gegebenen Reihenfolge auszugeben.
Schließlich sind z und k an eine benutzerdefinierte Funktion sort zu übergeben, die die
Zeichenketten lexikographisch sortiert entsprechend der vorgegebenen linearen Ordnung
in A. Die Funktion sort soll ihrerseits eine Funktion vgl aufrufen, mit der festgestellt werden kann, in welcher Beziehung zwei Zeichenketten bzgl. der lexikographischen Ordnung
zueinander stehen.
Zur Kontrolle ist auch das sortierte Array z auszugeben. Die beiden Ausgaben von z sind
mit Hilfe einer benutzerdefinierten Funktion print zu veranlassen.
Die zum Sortieren benötigte Zeit ist mit Hilfe der Systemuhr zu stoppen und auszugeben!
Zur Erinnerung (s. dazu auch Übungsaufgabe 4):
Für zwei nichtleere Zeichenketten s und t gilt genau dann s ≤ t, wenn gilt:
(length(s) ≤ length(t) ∧ ∀i(0 ≤ i ≤ (length(s) − 1) → si = ti )) ∨
∃r(0 ≤ r < min{length(s), length(t)} ∧ sr < tr ∧ ∀i(0 ≤ i < r → si = ti ))
Projektaufgabe 2:
Speicherung von binären Relationen R; Test auf Äquivalenzrelationseigenschaft; Erweiterung zur bzgl. ⊆ kleinsten R umfassenden
Äquivalenzrelation
Es sollen zunächst über die Tastatur eine natürliche Zahl n und dann geordnete Paare
(i, j) mit 0 ≤ i, j < n, die die binäre Relation R ⊆ {0, · · · , n − 1} × {0, · · · , n − 1} ausmachen sollen, eingegeben werden (Abbruch der Eingabe dann, wenn ein Paar mit einer
negativen Komponente eingegeben wurde). Diese Relation R ist auf die drei folgenden
Weisen abzuspeichern:
• durch ihre Adjazenzmatrix (siehe Folie 22), als dynamische Matrix zu definieren
• als einfach verkettete Liste Rli aller ihrer Paare
• als lineares Array Rar von Nachfolgerlisten der Elemente von {0, · · · , n − 1} (das ist
ein Array mit n Elementen, wobei Rar[i] eine einfach verkettete Liste aller Nachfolger von i bzgl. R ist; ist das Array selbst als Liste angelegt, so spricht man auch
von der Adjazenzlisten–Darstellung von R).
Beispielsweise könnte also die Relation R := {(0, 0), (0, 2), (0, 3), (1, 2), (2, 0), (2, 3)} in der
Menge {0, 1, 2, 3} wie folgt als einfach verkettete Liste Rli bzw. als Array Rar von Nachfolgerlisten abgespeichert sein:
Rli
Rar
0
0
0
0
2
2
0
3
1
2
2
0
2
3
3
2
0
3
(a) Schreiben Sie je eine benutzerdefinierte Funktion, durch die für die Darstellungen
von R als Adjazenzmatrix, als einfach verkettete Liste bzw. als Array von einfach
verketteten Listen überprüft wird, ob R eine Äquivalenzrelation in {0, · · · , n − 1}
ist oder nicht!
(b) Falls R keine Äquivalenzrelation ist, so soll durch das Programm die bzgl. ⊆ kleinste
Äquivalenzrelation S in {0, · · · , n − 1} bestimmt werden, für die R ⊆ S gilt! Diese
soll wieder in jedem der drei obigen Formate abgespeichert werden!
(c) R und S sind als Mengen ihrer geordneten Paare auszugeben!
Projektaufgabe 3:
Speicherung von Mengen mittels Hash–Tabellen; Durchschnitts–
und Vereinigungsbildung
Eine endliche Menge von ganzen Zahlen kann folgendermaßen mittels einer Hash–Tabelle
gespeichert werden:
Zunächst wird natürliche Zahl n > 0 vorgegeben. Dann wird ein eindimensionales Array
ht der Länge n mit Zeigern auf zunächst leere Listen von ganzen Zahlen definiert, dh., es
ist zunächst ht[i]=NULL für alle i mit 0 ≤ i < n. Um eine ganze Zahl k in die Tabelle
einzutragen, wird zunächst i:=k mod n gebildet (aufpassen, wenn k negativ ist, dann ist
−n ≤ i ≤ n − 1; falls also i < 0 ist, so ist genau einmal n zu i zu addieren, damit dann
0 ≤ i < n ist). Wenn dann k noch nicht in der bei ht[i] beginnenden Liste enthalten ist,
so wird k in diese Liste eingetragen, etwa am Anfang dieser Liste.
Beispiel: Falls n = 3 ist und man die 5 Zahlen -6, -1, 5, 7 und 9 auf obige Weise abspeichert, so ergibt sich die folgende Darstellung:
ht[0]
−6
ht[1]
7
ht[2]
−1
9
5
(Möchte man beispielsweise Zeichenketten abspeichern, so kann man diesen zunächst einen
Zahlenwert zuordnen, etwa indem die ASCII–Codes aller Vorkommen aller Zeichen addiert werden. Dieser Zahlenwert wird dann wieder wie oben modulo n modifiziert.)
Nun zur eigentlichen Programmieraufgabe:
Das Programm soll anfangs den Wert von obigem n sowie die Anzahlen m1 bzw. m2 der
Elemente der Mengen M1 bzw. M2 erfragen. Dann sind die beiden Mengen als Hash–
Tabellen mit zufälligen ganzen Zahlen vom Typ int zu füllen, wobei natürlich eine bestimmte Zahl in jeder Menge höchstens einmal vorkommen darf.
Es sind dann drei benutzerdefinierte Funktionen print, intersect bzw. union zu schreiben,
mit deren Hilfe folgendes getan werden soll:
• Die Elemente von M1 und von M2 sind auszugeben!
• Es ist die Menge M3 := M1 ∩ M2 zu bilden, als Hash–Tabelle abzuspeichern und
auszugeben!
• Es ist die Menge M4 := M1 ∪ M2 zu bilden, als Hash–Tabelle abzuspeichern und
auszugeben!
Projektaufgabe 4:
Programmierung eines wissenschaftlichen UPN–Rechners mit
double–Zahlen und den zweistelligen Operationen +, –, *, / sowie den einstelligen Operationen abs, neg, inv, sqr und sqrt
Mit Hilfe eines C–Programmes ist ein obiger Rechner zu simulieren, wobei auf dem Bildschirm der jeweilige Kellerinhalt darzustellen ist (das jeweilige top–Element soll auch oben
sein). Anfangs sei der Keller leer.
Jedes Mal, wenn eine Gleitpunktzahl eingegeben wird (Abschluss der Eingabe mit ENTER), ist diese zu kellern.
Wird eine einstellige Operation eingegeben (Abschluss der Eingabe wie immer mit ENTER) und der Keller ist nicht leer, so soll diese Operation das oberste Kellerelement
entsprechend verändern; falls jedoch der Keller leer ist, so soll eine Fehlermeldung erfolgen.
Wird eine zweistellige Operation eingegeben und es sind mindestens zwei Elemente im
Keller, so soll diese Operation auf die beiden obersten Kellerelemente angewendet werden, wobei danach der Keller ein Element weniger enthält. Das oberste Kellerelement
ist das Ergebnis der Operation. War jedoch höchstens ein Element im Keller, so soll die
Nichtdurchführbarkeit der Operation angezeigt werden.
Am Schluss einer Termwertberechnung darf dann nur noch eine Zahl im Keller stehen,
nämlich das Ergebnis.
Der Keller selbst ist als einfach verkettete Liste stack abzuspeichern, wobei die Verkettung
von oben nach unten erfolgen soll.
Projektaufgabe 5:
Prüfungsplanung auf der Basis eines Fächerkonfliktgraphen
Vom Programm sind anfangs die Anzahl n > 0 der Fächer (=Anzahl der Knoten des
Graphen) sowie die Anzahl k ≤ n ∗ (n − 1)/2 der Kanten des ungerichteten Fächerkonfliktgraphen zu erfragen. Die Fächer mögen durch die natürlichen Zahlen von 1 bis n
dargestellt werden, so dass also für die Knotenmenge Kn gilt: Kn:={1, · · · , n}. Es soll
Kn als einfach verkettete Liste im Computer abgespeichert werden.
Die k Kanten sind wahlweise über die Tastatur einzugeben oder zufällig zu erzeugen. Die
Menge Ka der Kanten ist ebenfalls als einfach verkettete Liste von Paaren von Fächern
zu speichern.
Jetzt sollen nacheinander maximale unabhängige Teilmengen der Knotenmenge gebildet
werden, wobei jede solche Menge die Menge der Prüfungsfächer eines Prüfungstages ist.
Diese Mengen sind ebenfalls je durch einfach verkettete Listen abzuspeichern, und alle
diese Listen sind in einer Liste der Prüfungstage zusammenzufassen.
Schließlich sind die Prüfungsfächer je Prüfungstag für alle Prüfungstage auszugeben.
Modifikation der Aufgabenstellung: Unmittelbar bevor die Prüfungsfächer eines
Prüfungstages berechnet werden, soll der Nutzer gefragt werden, welches Fach er auf
jeden Fall an diesem Tag unter den Prüfungsfächern haben möchte.
Zur Erinnerung: Eine Menge M heißt genau dann maximale unabhängige Teilmenge der
Knotenmenge Kn des Graphen (Kn, Ka), wenn gilt:
M ⊆ Kn ∧ M 6= ∅ ∧
∀a∀b(a ∈ M ∧ b ∈ M ∧ a 6= b → {a, b} ∈
/ Ka) ∧
∀a(a ∈ Kn \ M → ∃b(b ∈ M ∧ {a, b} ∈ Ka))
Herunterladen