Abitur NRW Informatik 2022 · LK · Haupttermin

Abiturprüfung Informatik in Nordrhein-Westfalen 2022, LK · Haupttermin: 10 Aufgaben mit Lösungen. Mit automatischer Korrektur.

Themen der Prüfung: Objektorientierte Modellierung mit Implementationsdiagrammen · Algorithmen auf Feldern und linearen Listen · Graphen und Graphenalgorithmen (LK) · Datenbankmodellierung und Normalisierung · SQL-Abfragen · Endliche Automaten · Grammatiken, Kellerautomaten und Grenzen endlicher Automaten · Datenschutz und Datensicherheit

Aufgabe 1 - Objektorientierte Modellierung · Objektorientierte Modellierung mit Implementationsdiagrammen

Aufgabenstellung: Schulveranstaltungs-Buchung

An der Turing-Schule finden regelmäßig verschiedene Schulveranstaltungen statt (z. B. Schulmusical, Schultheater). Früher entstanden vor dem Einlass zu einer Veranstaltung zum Teil lange Warteschlangen.

Damit alle Beteiligten besser planen können, soll man die Sitzplätze für eine Veranstaltung künftig vorab reservieren können. Deshalb wollen die Schülerinnen und Schüler des Informatikprojektkurses ein Buchungssystem für diese Veranstaltungen entwickeln.

Bewährt hat sich, die Aula für jede Veranstaltung gesondert zu bestuhlen. Die Stühle stehen dabei stets in Sitzplatzreihen. Innerhalb einer Veranstaltung hat jede Sitzplatzreihe dieselbe Anzahl an Stühlen.

Für eine Veranstaltung darf eine Person auch mehrere Sitzplätze reservieren. Ist die Veranstaltung schon ausgebucht, kann sich eine Person auf die Warteliste eintragen lassen, bei mehreren Platzwünschen auch mehrfach. Die Telefonnummer einer Person wird ausschließlich gespeichert, um sie bei Absagen von Veranstaltungen schnell zu erreichen.

Das folgende Implementationsdiagramm zeigt einen ersten Modellierungsentwurf zur Verwaltung der Veranstaltungen. Die Klassendokumentationen stehen im Anhang.

Anhang: Dokumentationen der verwendeten Klassen

Die Klasse Veranstaltungsverwaltung

Objekte der Klasse Veranstaltungsverwaltung verwalten Veranstaltungen.

Veranstaltungsverwaltung()

Ein Objekt der Klasse Veranstaltungsverwaltung wird initialisiert.

List<Veranstaltung> gibVeranstaltungen()

Eine Liste mit allen Veranstaltungen wird zurückgeliefert. Wenn keine Veranstaltung verwaltet wird, dann wird eine leere Liste zurückgegeben.

void fuegeHinzu(Veranstaltung pVeranstaltung)

Die im Parameter übergebene Veranstaltung wird hinzugefügt.

void reserviere(Veranstaltung pVeranstaltung, int pReihe, int pSitz, Person pPerson)

Für die Veranstaltung pVeranstaltung wird für den Platz (pReihe, pSitz) für die Person eine Reservierung vorgenommen. Falls für die entsprechende Veranstaltung an dem Platz bereits eine Reservierung vorliegt, dann wird diese überschrieben. Falls der Platz nicht existiert, pVeranstaltung null ist oder pPerson null ist, dann geschieht nichts.

void schreibeAufWarteliste(Veranstaltung pVeranstaltung, Person pPerson)

Das Personenobjekt pPerson wird an die Warteliste für die Veranstaltung pVeranstaltung angehängt. Falls pVeranstaltung null ist oder pPerson null ist, dann geschieht nichts.

Veranstaltung ermittleVeranstaltung(String pTermin, String pVeranstaltungsname)

Für den im Parameter übergebenen Termin und Veranstaltungsnamen wird das entsprechende Veranstaltungsobjekt zurückgeliefert. Falls es zu dem Termin keine Veranstaltung mit dem Namen gibt, wird null zurückgeliefert.

List<Veranstaltung> ermittleSortierte()

Die Methode soll eine neue Liste mit allen Veranstaltungsobjekten zurückliefern. Diese neue Liste soll nach der Anzahl der noch freien Plätze absteigend sortiert sein. Bei gleicher Anzahl der noch freien Plätze spielt die Reihenfolge dieser Veranstaltungen untereinander keine Rolle.

Die Klasse Veranstaltung

Objekte der Klasse Veranstaltung verwalten Termine, Veranstaltungsnamen und die Sitzplätze mit den entsprechenden Reservierungen der Personen.

Veranstaltung(String pTermin, String pVeranstaltungsname, int pAnzahlReihen, int pAnzahlPlaetzeProReihe)

Ein Objekt der Klasse Veranstaltung wird initialisiert mit dem Termin, dem Veranstaltungsnamen, der Anzahl der Sitzplatzreihen und der Anzahl der Plätze pro Reihe.

String gibTermin()

Der Termin der Veranstaltung wird zurückgeliefert.

String gibVeranstaltungsname()

Der Veranstaltungsname der Veranstaltung wird zurückgeliefert.

int gibAnzahlFreiePlaetze()

Die Anzahl der noch freien Plätze der Veranstaltung wird zurückgeliefert.

Person gibReservierung(int pReihe, int pSitz)

Das Personenobjekt mit einer Reservierung für den Platz (pReihe, pSitz) wird zurückgeliefert. Falls der Platz nicht reserviert ist, wird null zurückgeliefert.

void reserviere(int pReihe, int pSitz, Person pPerson)

Für die Veranstaltung wird für den Platz (pReihe, pSitz) für die Person eine Reservierung vorgenommen. Falls an dem Platz bereits eine Reservierung vorliegt, dann wird diese überschrieben. Falls der Platz nicht existiert oder pPerson null ist, dann geschieht nichts.

void loescheReservierung(int pReihe, int pSitz)

Für die Veranstaltung wird die Reservierung für den Platz (pReihe, pSitz) gelöscht. Falls der Platz nicht existiert, dann geschieht nichts.

void schreibeAufWarteliste(Person pPerson)

Das Personenobjekt pPerson wird an die Warteliste für die Veranstaltung angehängt. Falls pPerson null ist, dann geschieht nichts.

void macheEtwas(int pAnzahl)

Diese Methode ist Bestandteil der Teilaufgabe b).

Die Klasse Person

Objekte der Klasse Person verwalten einen Namen und eine Telefonnummer einer Person.

Person(String pName, String pTelefonnummer)

Ein Objekt der Klasse Person wird initialisiert mit dem Namen und der Telefonnummer.

String gibName()

Der Name der Person wird zurückgeliefert.

String gibTelefonnummer()

Die Telefonnummer der Person wird zurückgeliefert.

boolean istGleich(Person pPerson)

Wenn das Personenobjekt inhaltlich mit dem im Parameter übergebenen Personenobjekt pPerson gleich ist, dann wird true zurückgeliefert und sonst false. Für die Inhaltsgleichheit müssen die jeweiligen Namen und Telefonnummern übereinstimmen.

Die generische Klasse Queue

Objekte der generischen Klasse Queue (Warteschlange) verwalten beliebige Objekte vom Typ ContentType nach dem First-In-First-Out-Prinzip, d. h., das zuerst abgelegte Objekt wird als erstes wieder entnommen. Alle Methoden haben eine konstante Laufzeit, unabhängig von der Anzahl der verwalteten Objekte.

Queue()

Eine leere Schlange wird erzeugt. Objekte, die in dieser Schlange verwaltet werden, müssen vom Typ ContentType sein.

boolean isEmpty()

Die Anfrage liefert den Wert true, wenn die Schlange keine Objekte enthält, sonst liefert sie den Wert false.

void enqueue(ContentType pContent)

Das Objekt pContent wird an die Schlange angehängt. Falls pContent gleich null ist, bleibt die Schlange unverändert.

void dequeue()

Das erste Objekt wird aus der Schlange entfernt. Falls die Schlange leer ist, wird sie nicht verändert.

ContentType front()

Die Anfrage liefert das erste Objekt der Schlange. Die Schlange bleibt unverändert. Falls die Schlange leer ist, wird null zurückgegeben.

Die generische Klasse List

Objekte der generischen Klasse List verwalten beliebig viele, linear angeordnete Objekte vom Typ ContentType. Auf höchstens ein Listenobjekt, aktuelles Objekt genannt, kann jeweils zugegriffen werden. Wenn eine Liste leer ist, vollständig durchlaufen wurde oder das aktuelle Objekt am Ende der Liste gelöscht wurde, gibt es kein aktuelles Objekt. Das erste oder das letzte Objekt einer Liste kann durch einen Auftrag zum aktuellen Objekt gemacht werden. Außerdem kann das dem aktuellen Objekt folgende Listenobjekt zum neuen aktuellen Objekt werden. Das aktuelle Objekt kann gelesen, verändert oder gelöscht werden. Außerdem kann vor dem aktuellen Objekt ein Listenobjekt eingefügt werden.

List()

Eine leere Liste wird erzeugt.

boolean isEmpty()

Die Anfrage liefert den Wert true, wenn die Liste keine Objekte enthält, sonst liefert sie den Wert false.

boolean hasAccess()

Die Anfrage liefert den Wert true, wenn es ein aktuelles Objekt gibt, sonst liefert sie den Wert false.

void next()

Falls die Liste nicht leer ist, es ein aktuelles Objekt gibt und dieses nicht das letzte Objekt der Liste ist, wird das dem aktuellen Objekt in der Liste folgende Objekt zum aktuellen Objekt, andernfalls gibt es nach Ausführung des Auftrags kein aktuelles Objekt, d. h., hasAccess() liefert den Wert false.

void toFirst()

Falls die Liste nicht leer ist, wird das erste Objekt der Liste aktuelles Objekt. Ist die Liste leer, geschieht nichts.

void toLast()

Falls die Liste nicht leer ist, wird das letzte Objekt der Liste aktuelles Objekt. Ist die Liste leer, geschieht nichts.

ContentType getContent()

Falls es ein aktuelles Objekt gibt (hasAccess() == true), wird das aktuelle Objekt zurückgegeben. Andernfalls (hasAccess() == false) gibt die Anfrage den Wert null zurück.

void setContent(ContentType pContent)

Falls es ein aktuelles Objekt gibt (hasAccess() == true) und pContent ungleich null ist, wird das aktuelle Objekt durch pContent ersetzt. Sonst bleibt die Liste unverändert.

void append(ContentType pContent)

Ein neues Objekt pContent wird am Ende der Liste eingefügt. Das aktuelle Objekt bleibt unverändert. Wenn die Liste leer ist, wird das Objekt pContent in die Liste eingefügt und es gibt weiterhin kein aktuelles Objekt (hasAccess() == false). Falls pContent gleich null ist, bleibt die Liste unverändert.

void insert(ContentType pContent)

Falls es ein aktuelles Objekt gibt (hasAccess() == true), wird ein neues Objekt pContent vor dem aktuellen Objekt in die Liste eingefügt. Das aktuelle Objekt bleibt unverändert. Falls die Liste leer ist und es somit kein aktuelles Objekt gibt (hasAccess() == false), wird pContent in die Liste eingefügt und es gibt weiterhin kein aktuelles Objekt. Falls es kein aktuelles Objekt gibt (hasAccess() == false) und die Liste nicht leer ist oder pContent == null ist, bleibt die Liste unverändert.

void concat(List<ContentType> pList)

Die Liste pList wird an die Liste angehängt. Anschließend wird pList eine leere Liste. Das aktuelle Objekt bleibt unverändert. Falls es sich bei der Liste und pList um dasselbe Objekt handelt, pList == null oder eine leere Liste ist, bleibt die Liste unverändert.

void remove()

Falls es ein aktuelles Objekt gibt (hasAccess() == true), wird das aktuelle Objekt gelöscht und das Objekt hinter dem gelöschten Objekt wird zum aktuellen Objekt. Wird das Objekt, das am Ende der Liste steht, gelöscht, gibt es kein aktuelles Objekt mehr (hasAccess() == false). Wenn die Liste leer ist oder es kein aktuelles Objekt gibt (hasAccess() == false), bleibt die Liste unverändert.

Teilaufgabe a)

a.1

Beschreiben Sie, in welchen Beziehungen die Klassen der in Abbildung 2 dargestellten Teilmodellierung zueinander stehen.

[3 Punkte]

a.2

Begründen Sie unter Bezug auf den Sachkontext, weshalb sich eine Schlange (Queue) für die Umsetzung der Datensammlungen der Warteliste eignet.

[2 Punkte]

a.3

Begründen Sie unter Bezug auf den Sachkontext, weshalb es zweckmäßig ist, die Sitzplätze samt den zugehörigen Reservierungen der Personen als zweidimensionales Feld (Array) statt als dynamische Datenstruktur umzusetzen.

[2 Punkte]

Teilaufgabe d)

Nach Absprache mit der Schulleitung wollen die Schülerinnen und Schüler ihr Projekt ausbauen. Dabei sollen zusätzlich die folgenden Anforderungen realisiert werden:

i. Künftig soll die Schule für jede Veranstaltung einen einheitlichen Eintrittspreis je Sitzplatz festlegen können. Dieser Preis muss gespeichert werden. Außerdem sollen sowohl der Eintrittspreis als auch die anhand der Reservierungen berechnete Summe der Eintrittsgelder abfragbar sein.

ii. Pro Veranstaltung soll sich klären lassen, ob in einer bestimmten Sitzplatzreihe noch eine gewünschte Anzahl nebeneinander liegender Plätze frei ist. Ist das der Fall, soll die Nummer des ersten Sitzes dieser zusammenhängenden freien Plätze geliefert werden. Stehen in der gewählten Reihe nicht genügend nebeneinander liegende freie Plätze zur Verfügung, soll auch dies in passender Form zurückgemeldet werden.

iii. Jede Person soll die von ihr gebuchten Veranstaltungen ausgeben können.

d.1

Modellieren Sie die oben aufgeführten Anforderungen, indem Sie das Implementationsdiagramm aus Abbildung 2 erweitern.

[9 Punkte]

Hinweis: Klassen, Beziehungen, Methoden und Attribute aus Abbildung 2, die unverändert bleiben, brauchen nicht erneut aufgeführt zu werden. Laden Sie ein Foto Ihrer Diagrammerweiterung hoch oder beschreiben Sie die Änderungen an den Klassen genau.

d.2

Erläutern Sie, auf welche Weise Ihr Implementationsdiagramm die zweite und die dritte Anforderung umsetzt.

[4 Punkte]

Aufgabe 1 - Algorithmen auf Feldern und Listen · Algorithmen auf Feldern und linearen Listen

Aufgabenstellung: Schulveranstaltungs-Buchung

An der Turing-Schule finden regelmäßig verschiedene Schulveranstaltungen statt (z. B. Schulmusical, Schultheater). Früher entstanden vor dem Einlass zu einer Veranstaltung zum Teil lange Warteschlangen.

Damit alle Beteiligten besser planen können, soll man die Sitzplätze für eine Veranstaltung künftig vorab reservieren können. Deshalb wollen die Schülerinnen und Schüler des Informatikprojektkurses ein Buchungssystem für diese Veranstaltungen entwickeln.

Bewährt hat sich, die Aula für jede Veranstaltung gesondert zu bestuhlen. Die Stühle stehen dabei stets in Sitzplatzreihen. Innerhalb einer Veranstaltung hat jede Sitzplatzreihe dieselbe Anzahl an Stühlen.

Für eine Veranstaltung darf eine Person auch mehrere Sitzplätze reservieren. Ist die Veranstaltung schon ausgebucht, kann sich eine Person auf die Warteliste eintragen lassen, bei mehreren Platzwünschen auch mehrfach. Die Telefonnummer einer Person wird ausschließlich gespeichert, um sie bei Absagen von Veranstaltungen schnell zu erreichen.

Das folgende Implementationsdiagramm zeigt einen ersten Modellierungsentwurf zur Verwaltung der Veranstaltungen. Die Klassendokumentationen stehen im Anhang.

Anhang: Dokumentationen der verwendeten Klassen

Die Klasse Veranstaltungsverwaltung

Objekte der Klasse Veranstaltungsverwaltung verwalten Veranstaltungen.

Veranstaltungsverwaltung()

Ein Objekt der Klasse Veranstaltungsverwaltung wird initialisiert.

List<Veranstaltung> gibVeranstaltungen()

Eine Liste mit allen Veranstaltungen wird zurückgeliefert. Wenn keine Veranstaltung verwaltet wird, dann wird eine leere Liste zurückgegeben.

void fuegeHinzu(Veranstaltung pVeranstaltung)

Die im Parameter übergebene Veranstaltung wird hinzugefügt.

void reserviere(Veranstaltung pVeranstaltung, int pReihe, int pSitz, Person pPerson)

Für die Veranstaltung pVeranstaltung wird für den Platz (pReihe, pSitz) für die Person eine Reservierung vorgenommen. Falls für die entsprechende Veranstaltung an dem Platz bereits eine Reservierung vorliegt, dann wird diese überschrieben. Falls der Platz nicht existiert, pVeranstaltung null ist oder pPerson null ist, dann geschieht nichts.

void schreibeAufWarteliste(Veranstaltung pVeranstaltung, Person pPerson)

Das Personenobjekt pPerson wird an die Warteliste für die Veranstaltung pVeranstaltung angehängt. Falls pVeranstaltung null ist oder pPerson null ist, dann geschieht nichts.

Veranstaltung ermittleVeranstaltung(String pTermin, String pVeranstaltungsname)

Für den im Parameter übergebenen Termin und Veranstaltungsnamen wird das entsprechende Veranstaltungsobjekt zurückgeliefert. Falls es zu dem Termin keine Veranstaltung mit dem Namen gibt, wird null zurückgeliefert.

List<Veranstaltung> ermittleSortierte()

Die Methode soll eine neue Liste mit allen Veranstaltungsobjekten zurückliefern. Diese neue Liste soll nach der Anzahl der noch freien Plätze absteigend sortiert sein. Bei gleicher Anzahl der noch freien Plätze spielt die Reihenfolge dieser Veranstaltungen untereinander keine Rolle.

Die Klasse Veranstaltung

Objekte der Klasse Veranstaltung verwalten Termine, Veranstaltungsnamen und die Sitzplätze mit den entsprechenden Reservierungen der Personen.

Veranstaltung(String pTermin, String pVeranstaltungsname, int pAnzahlReihen, int pAnzahlPlaetzeProReihe)

Ein Objekt der Klasse Veranstaltung wird initialisiert mit dem Termin, dem Veranstaltungsnamen, der Anzahl der Sitzplatzreihen und der Anzahl der Plätze pro Reihe.

String gibTermin()

Der Termin der Veranstaltung wird zurückgeliefert.

String gibVeranstaltungsname()

Der Veranstaltungsname der Veranstaltung wird zurückgeliefert.

int gibAnzahlFreiePlaetze()

Die Anzahl der noch freien Plätze der Veranstaltung wird zurückgeliefert.

Person gibReservierung(int pReihe, int pSitz)

Das Personenobjekt mit einer Reservierung für den Platz (pReihe, pSitz) wird zurückgeliefert. Falls der Platz nicht reserviert ist, wird null zurückgeliefert.

void reserviere(int pReihe, int pSitz, Person pPerson)

Für die Veranstaltung wird für den Platz (pReihe, pSitz) für die Person eine Reservierung vorgenommen. Falls an dem Platz bereits eine Reservierung vorliegt, dann wird diese überschrieben. Falls der Platz nicht existiert oder pPerson null ist, dann geschieht nichts.

void loescheReservierung(int pReihe, int pSitz)

Für die Veranstaltung wird die Reservierung für den Platz (pReihe, pSitz) gelöscht. Falls der Platz nicht existiert, dann geschieht nichts.

void schreibeAufWarteliste(Person pPerson)

Das Personenobjekt pPerson wird an die Warteliste für die Veranstaltung angehängt. Falls pPerson null ist, dann geschieht nichts.

void macheEtwas(int pAnzahl)

Diese Methode ist Bestandteil der Teilaufgabe b).

Die Klasse Person

Objekte der Klasse Person verwalten einen Namen und eine Telefonnummer einer Person.

Person(String pName, String pTelefonnummer)

Ein Objekt der Klasse Person wird initialisiert mit dem Namen und der Telefonnummer.

String gibName()

Der Name der Person wird zurückgeliefert.

String gibTelefonnummer()

Die Telefonnummer der Person wird zurückgeliefert.

boolean istGleich(Person pPerson)

Wenn das Personenobjekt inhaltlich mit dem im Parameter übergebenen Personenobjekt pPerson gleich ist, dann wird true zurückgeliefert und sonst false. Für die Inhaltsgleichheit müssen die jeweiligen Namen und Telefonnummern übereinstimmen.

Die generische Klasse Queue

Objekte der generischen Klasse Queue (Warteschlange) verwalten beliebige Objekte vom Typ ContentType nach dem First-In-First-Out-Prinzip, d. h., das zuerst abgelegte Objekt wird als erstes wieder entnommen. Alle Methoden haben eine konstante Laufzeit, unabhängig von der Anzahl der verwalteten Objekte.

Queue()

Eine leere Schlange wird erzeugt. Objekte, die in dieser Schlange verwaltet werden, müssen vom Typ ContentType sein.

boolean isEmpty()

Die Anfrage liefert den Wert true, wenn die Schlange keine Objekte enthält, sonst liefert sie den Wert false.

void enqueue(ContentType pContent)

Das Objekt pContent wird an die Schlange angehängt. Falls pContent gleich null ist, bleibt die Schlange unverändert.

void dequeue()

Das erste Objekt wird aus der Schlange entfernt. Falls die Schlange leer ist, wird sie nicht verändert.

ContentType front()

Die Anfrage liefert das erste Objekt der Schlange. Die Schlange bleibt unverändert. Falls die Schlange leer ist, wird null zurückgegeben.

Die generische Klasse List

Objekte der generischen Klasse List verwalten beliebig viele, linear angeordnete Objekte vom Typ ContentType. Auf höchstens ein Listenobjekt, aktuelles Objekt genannt, kann jeweils zugegriffen werden. Wenn eine Liste leer ist, vollständig durchlaufen wurde oder das aktuelle Objekt am Ende der Liste gelöscht wurde, gibt es kein aktuelles Objekt. Das erste oder das letzte Objekt einer Liste kann durch einen Auftrag zum aktuellen Objekt gemacht werden. Außerdem kann das dem aktuellen Objekt folgende Listenobjekt zum neuen aktuellen Objekt werden. Das aktuelle Objekt kann gelesen, verändert oder gelöscht werden. Außerdem kann vor dem aktuellen Objekt ein Listenobjekt eingefügt werden.

List()

Eine leere Liste wird erzeugt.

boolean isEmpty()

Die Anfrage liefert den Wert true, wenn die Liste keine Objekte enthält, sonst liefert sie den Wert false.

boolean hasAccess()

Die Anfrage liefert den Wert true, wenn es ein aktuelles Objekt gibt, sonst liefert sie den Wert false.

void next()

Falls die Liste nicht leer ist, es ein aktuelles Objekt gibt und dieses nicht das letzte Objekt der Liste ist, wird das dem aktuellen Objekt in der Liste folgende Objekt zum aktuellen Objekt, andernfalls gibt es nach Ausführung des Auftrags kein aktuelles Objekt, d. h., hasAccess() liefert den Wert false.

void toFirst()

Falls die Liste nicht leer ist, wird das erste Objekt der Liste aktuelles Objekt. Ist die Liste leer, geschieht nichts.

void toLast()

Falls die Liste nicht leer ist, wird das letzte Objekt der Liste aktuelles Objekt. Ist die Liste leer, geschieht nichts.

ContentType getContent()

Falls es ein aktuelles Objekt gibt (hasAccess() == true), wird das aktuelle Objekt zurückgegeben. Andernfalls (hasAccess() == false) gibt die Anfrage den Wert null zurück.

void setContent(ContentType pContent)

Falls es ein aktuelles Objekt gibt (hasAccess() == true) und pContent ungleich null ist, wird das aktuelle Objekt durch pContent ersetzt. Sonst bleibt die Liste unverändert.

void append(ContentType pContent)

Ein neues Objekt pContent wird am Ende der Liste eingefügt. Das aktuelle Objekt bleibt unverändert. Wenn die Liste leer ist, wird das Objekt pContent in die Liste eingefügt und es gibt weiterhin kein aktuelles Objekt (hasAccess() == false). Falls pContent gleich null ist, bleibt die Liste unverändert.

void insert(ContentType pContent)

Falls es ein aktuelles Objekt gibt (hasAccess() == true), wird ein neues Objekt pContent vor dem aktuellen Objekt in die Liste eingefügt. Das aktuelle Objekt bleibt unverändert. Falls die Liste leer ist und es somit kein aktuelles Objekt gibt (hasAccess() == false), wird pContent in die Liste eingefügt und es gibt weiterhin kein aktuelles Objekt. Falls es kein aktuelles Objekt gibt (hasAccess() == false) und die Liste nicht leer ist oder pContent == null ist, bleibt die Liste unverändert.

void concat(List<ContentType> pList)

Die Liste pList wird an die Liste angehängt. Anschließend wird pList eine leere Liste. Das aktuelle Objekt bleibt unverändert. Falls es sich bei der Liste und pList um dasselbe Objekt handelt, pList == null oder eine leere Liste ist, bleibt die Liste unverändert.

void remove()

Falls es ein aktuelles Objekt gibt (hasAccess() == true), wird das aktuelle Objekt gelöscht und das Objekt hinter dem gelöschten Objekt wird zum aktuellen Objekt. Wird das Objekt, das am Ende der Liste steht, gelöscht, gibt es kein aktuelles Objekt mehr (hasAccess() == false). Wenn die Liste leer ist oder es kein aktuelles Objekt gibt (hasAccess() == false), bleibt die Liste unverändert.

Teilaufgabe b)

In der Klasse Veranstaltung findet eine Schülerin die nicht dokumentierte Methode macheEtwas.

1 public void macheEtwas(int pAnzahl) {

2

if (pAnzahl > 0) {

3

int reihen = sitzplaetze.length;

4

int sitze = sitzplaetze[0].length;

5

int rNeu = reihen + pAnzahl;

6

Person[][] sitzplaetzeNeu = new Person[rNeu][sitze];

7

for (int r = 0; r < reihen; r++) {

8

for (int s = 0; s < sitze; s++) {

9

sitzplaetzeNeu[r][s] = sitzplaetze[r][s];

10

}

11

}

12

for (int r = reihen; r < rNeu; r++) {

13

for (int s = 0; s < sitze; s++) {

14

if (sitzplaetzeNeu[r][s] == null) {

15

sitzplaetzeNeu[r][s] = warteliste.front();

16

warteliste.dequeue();

17

}

18

}

19

}

20

sitzplaetze = sitzplaetzeNeu;

21

}

22 } Es wird angenommen, dass die Methode macheEtwas für die in Abbildung 1 gezeigte Veranstaltung mit dem Parameter pAnzahl = 2 aufgerufen wird.

Nehmen Sie an, dass das Objekt warteliste folgendermaßen gefüllt ist:

b.1)

Analysieren Sie die Methode anhand dieser Belegungen und der Beispieldaten aus Abbildung 1 und erläutern Sie, wie die Methode arbeitet und wie sich dabei die Belegung der Sitzplätze und der Warteliste verändert. [6 Punkte]

b.2)

Erläutern Sie, welchen Zweck die Methode im Sachzusammenhang erfüllt. [3 Punkte]

b.3)

Beurteilen Sie, welche Bedeutung die Verzweigung in Zeile 2 im Sachkontext hat. [2 Punkte]

b.4)

Beurteilen Sie, ob die Verzweigung in Zeile 14 notwendig ist. [2 Punkte]

Teilaufgabe c)

In der Klasse Veranstaltungsverwaltung soll eine Methode mit folgendem Methodenkopf ergänzt werden:

public List<Veranstaltung> ermittleSortierte() Die Methode soll eine neue Liste zurückgeben, die alle Veranstaltungsobjekte enthält und absteigend nach der Zahl der noch freien Plätze geordnet ist. Haben Veranstaltungen gleich viele freie Plätze, ist ihre Reihenfolge zueinander beliebig.

c.1)

Entwickeln und erläutern Sie für die Methode ermittleSortierte ein algorithmisches Verfahren. [5 Punkte]

c.2)

Implementieren Sie die Methode ermittleSortierte in Java. [7 Punkte]

Aufgabe 1 - Datenschutz · Datenschutz und Datensicherheit

Aufgabenstellung: Schulveranstaltungs-Buchung

An der Turing-Schule finden regelmäßig verschiedene Schulveranstaltungen statt (z. B. Schulmusical, Schultheater). Früher entstanden vor dem Einlass zu einer Veranstaltung zum Teil lange Warteschlangen.

Damit alle Beteiligten besser planen können, soll man die Sitzplätze für eine Veranstaltung künftig vorab reservieren können. Deshalb wollen die Schülerinnen und Schüler des Informatikprojektkurses ein Buchungssystem für diese Veranstaltungen entwickeln.

Bewährt hat sich, die Aula für jede Veranstaltung gesondert zu bestuhlen. Die Stühle stehen dabei stets in Sitzplatzreihen. Innerhalb einer Veranstaltung hat jede Sitzplatzreihe dieselbe Anzahl an Stühlen.

Für eine Veranstaltung darf eine Person auch mehrere Sitzplätze reservieren. Ist die Veranstaltung schon ausgebucht, kann sich eine Person auf die Warteliste eintragen lassen, bei mehreren Platzwünschen auch mehrfach. Die Telefonnummer einer Person wird ausschließlich gespeichert, um sie bei Absagen von Veranstaltungen schnell zu erreichen.

Das folgende Implementationsdiagramm zeigt einen ersten Modellierungsentwurf zur Verwaltung der Veranstaltungen. Die Klassendokumentationen stehen im Anhang.

Anhang: Dokumentationen der verwendeten Klassen

Die Klasse Veranstaltungsverwaltung

Objekte der Klasse Veranstaltungsverwaltung verwalten Veranstaltungen.

Veranstaltungsverwaltung()

Ein Objekt der Klasse Veranstaltungsverwaltung wird initialisiert.

List<Veranstaltung> gibVeranstaltungen()

Eine Liste mit allen Veranstaltungen wird zurückgeliefert. Wenn keine Veranstaltung verwaltet wird, dann wird eine leere Liste zurückgegeben.

void fuegeHinzu(Veranstaltung pVeranstaltung)

Die im Parameter übergebene Veranstaltung wird hinzugefügt.

void reserviere(Veranstaltung pVeranstaltung, int pReihe, int pSitz, Person pPerson)

Für die Veranstaltung pVeranstaltung wird für den Platz (pReihe, pSitz) für die Person eine Reservierung vorgenommen. Falls für die entsprechende Veranstaltung an dem Platz bereits eine Reservierung vorliegt, dann wird diese überschrieben. Falls der Platz nicht existiert, pVeranstaltung null ist oder pPerson null ist, dann geschieht nichts.

void schreibeAufWarteliste(Veranstaltung pVeranstaltung, Person pPerson)

Das Personenobjekt pPerson wird an die Warteliste für die Veranstaltung pVeranstaltung angehängt. Falls pVeranstaltung null ist oder pPerson null ist, dann geschieht nichts.

Veranstaltung ermittleVeranstaltung(String pTermin, String pVeranstaltungsname)

Für den im Parameter übergebenen Termin und Veranstaltungsnamen wird das entsprechende Veranstaltungsobjekt zurückgeliefert. Falls es zu dem Termin keine Veranstaltung mit dem Namen gibt, wird null zurückgeliefert.

List<Veranstaltung> ermittleSortierte()

Die Methode soll eine neue Liste mit allen Veranstaltungsobjekten zurückliefern. Diese neue Liste soll nach der Anzahl der noch freien Plätze absteigend sortiert sein. Bei gleicher Anzahl der noch freien Plätze spielt die Reihenfolge dieser Veranstaltungen untereinander keine Rolle.

Die Klasse Veranstaltung

Objekte der Klasse Veranstaltung verwalten Termine, Veranstaltungsnamen und die Sitzplätze mit den entsprechenden Reservierungen der Personen.

Veranstaltung(String pTermin, String pVeranstaltungsname, int pAnzahlReihen, int pAnzahlPlaetzeProReihe)

Ein Objekt der Klasse Veranstaltung wird initialisiert mit dem Termin, dem Veranstaltungsnamen, der Anzahl der Sitzplatzreihen und der Anzahl der Plätze pro Reihe.

String gibTermin()

Der Termin der Veranstaltung wird zurückgeliefert.

String gibVeranstaltungsname()

Der Veranstaltungsname der Veranstaltung wird zurückgeliefert.

int gibAnzahlFreiePlaetze()

Die Anzahl der noch freien Plätze der Veranstaltung wird zurückgeliefert.

Person gibReservierung(int pReihe, int pSitz)

Das Personenobjekt mit einer Reservierung für den Platz (pReihe, pSitz) wird zurückgeliefert. Falls der Platz nicht reserviert ist, wird null zurückgeliefert.

void reserviere(int pReihe, int pSitz, Person pPerson)

Für die Veranstaltung wird für den Platz (pReihe, pSitz) für die Person eine Reservierung vorgenommen. Falls an dem Platz bereits eine Reservierung vorliegt, dann wird diese überschrieben. Falls der Platz nicht existiert oder pPerson null ist, dann geschieht nichts.

void loescheReservierung(int pReihe, int pSitz)

Für die Veranstaltung wird die Reservierung für den Platz (pReihe, pSitz) gelöscht. Falls der Platz nicht existiert, dann geschieht nichts.

void schreibeAufWarteliste(Person pPerson)

Das Personenobjekt pPerson wird an die Warteliste für die Veranstaltung angehängt. Falls pPerson null ist, dann geschieht nichts.

void macheEtwas(int pAnzahl)

Diese Methode ist Bestandteil der Teilaufgabe b).

Die Klasse Person

Objekte der Klasse Person verwalten einen Namen und eine Telefonnummer einer Person.

Person(String pName, String pTelefonnummer)

Ein Objekt der Klasse Person wird initialisiert mit dem Namen und der Telefonnummer.

String gibName()

Der Name der Person wird zurückgeliefert.

String gibTelefonnummer()

Die Telefonnummer der Person wird zurückgeliefert.

boolean istGleich(Person pPerson)

Wenn das Personenobjekt inhaltlich mit dem im Parameter übergebenen Personenobjekt pPerson gleich ist, dann wird true zurückgeliefert und sonst false. Für die Inhaltsgleichheit müssen die jeweiligen Namen und Telefonnummern übereinstimmen.

Die generische Klasse Queue

Objekte der generischen Klasse Queue (Warteschlange) verwalten beliebige Objekte vom Typ ContentType nach dem First-In-First-Out-Prinzip, d. h., das zuerst abgelegte Objekt wird als erstes wieder entnommen. Alle Methoden haben eine konstante Laufzeit, unabhängig von der Anzahl der verwalteten Objekte.

Queue()

Eine leere Schlange wird erzeugt. Objekte, die in dieser Schlange verwaltet werden, müssen vom Typ ContentType sein.

boolean isEmpty()

Die Anfrage liefert den Wert true, wenn die Schlange keine Objekte enthält, sonst liefert sie den Wert false.

void enqueue(ContentType pContent)

Das Objekt pContent wird an die Schlange angehängt. Falls pContent gleich null ist, bleibt die Schlange unverändert.

void dequeue()

Das erste Objekt wird aus der Schlange entfernt. Falls die Schlange leer ist, wird sie nicht verändert.

ContentType front()

Die Anfrage liefert das erste Objekt der Schlange. Die Schlange bleibt unverändert. Falls die Schlange leer ist, wird null zurückgegeben.

Die generische Klasse List

Objekte der generischen Klasse List verwalten beliebig viele, linear angeordnete Objekte vom Typ ContentType. Auf höchstens ein Listenobjekt, aktuelles Objekt genannt, kann jeweils zugegriffen werden. Wenn eine Liste leer ist, vollständig durchlaufen wurde oder das aktuelle Objekt am Ende der Liste gelöscht wurde, gibt es kein aktuelles Objekt. Das erste oder das letzte Objekt einer Liste kann durch einen Auftrag zum aktuellen Objekt gemacht werden. Außerdem kann das dem aktuellen Objekt folgende Listenobjekt zum neuen aktuellen Objekt werden. Das aktuelle Objekt kann gelesen, verändert oder gelöscht werden. Außerdem kann vor dem aktuellen Objekt ein Listenobjekt eingefügt werden.

List()

Eine leere Liste wird erzeugt.

boolean isEmpty()

Die Anfrage liefert den Wert true, wenn die Liste keine Objekte enthält, sonst liefert sie den Wert false.

boolean hasAccess()

Die Anfrage liefert den Wert true, wenn es ein aktuelles Objekt gibt, sonst liefert sie den Wert false.

void next()

Falls die Liste nicht leer ist, es ein aktuelles Objekt gibt und dieses nicht das letzte Objekt der Liste ist, wird das dem aktuellen Objekt in der Liste folgende Objekt zum aktuellen Objekt, andernfalls gibt es nach Ausführung des Auftrags kein aktuelles Objekt, d. h., hasAccess() liefert den Wert false.

void toFirst()

Falls die Liste nicht leer ist, wird das erste Objekt der Liste aktuelles Objekt. Ist die Liste leer, geschieht nichts.

void toLast()

Falls die Liste nicht leer ist, wird das letzte Objekt der Liste aktuelles Objekt. Ist die Liste leer, geschieht nichts.

ContentType getContent()

Falls es ein aktuelles Objekt gibt (hasAccess() == true), wird das aktuelle Objekt zurückgegeben. Andernfalls (hasAccess() == false) gibt die Anfrage den Wert null zurück.

void setContent(ContentType pContent)

Falls es ein aktuelles Objekt gibt (hasAccess() == true) und pContent ungleich null ist, wird das aktuelle Objekt durch pContent ersetzt. Sonst bleibt die Liste unverändert.

void append(ContentType pContent)

Ein neues Objekt pContent wird am Ende der Liste eingefügt. Das aktuelle Objekt bleibt unverändert. Wenn die Liste leer ist, wird das Objekt pContent in die Liste eingefügt und es gibt weiterhin kein aktuelles Objekt (hasAccess() == false). Falls pContent gleich null ist, bleibt die Liste unverändert.

void insert(ContentType pContent)

Falls es ein aktuelles Objekt gibt (hasAccess() == true), wird ein neues Objekt pContent vor dem aktuellen Objekt in die Liste eingefügt. Das aktuelle Objekt bleibt unverändert. Falls die Liste leer ist und es somit kein aktuelles Objekt gibt (hasAccess() == false), wird pContent in die Liste eingefügt und es gibt weiterhin kein aktuelles Objekt. Falls es kein aktuelles Objekt gibt (hasAccess() == false) und die Liste nicht leer ist oder pContent == null ist, bleibt die Liste unverändert.

void concat(List<ContentType> pList)

Die Liste pList wird an die Liste angehängt. Anschließend wird pList eine leere Liste. Das aktuelle Objekt bleibt unverändert. Falls es sich bei der Liste und pList um dasselbe Objekt handelt, pList == null oder eine leere Liste ist, bleibt die Liste unverändert.

void remove()

Falls es ein aktuelles Objekt gibt (hasAccess() == true), wird das aktuelle Objekt gelöscht und das Objekt hinter dem gelöschten Objekt wird zum aktuellen Objekt. Wird das Objekt, das am Ende der Liste steht, gelöscht, gibt es kein aktuelles Objekt mehr (hasAccess() == false). Wenn die Liste leer ist oder es kein aktuelles Objekt gibt (hasAccess() == false), bleibt die Liste unverändert.

e)

Wenn Veranstaltungen kurzfristig abgesagt wurden, ließen sich leider nicht alle Personen rechtzeitig telefonisch erreichen. Deshalb soll ausschließlich zur schnellen Benachrichtigung bei Absagen zusätzlich verpflichtend die E-Mail-Adresse jeder Person gespeichert werden.

Zusätzlich bittet der Schulleiter die Projektgruppe, eine von ihm vorbereitete E-Mail zu prüfen. Diese E-Mail enthält nur Hinweise auf künftige Schulveranstaltungen. Er begründet, er wolle künftig jeden Monat eine solche E-Mail als Service an sämtliche im Buchungssystem erfassten Personen schicken, weil diese sich ohnehin für die Schulveranstaltungen interessierten.

Beurteilen Sie den Vorschlag des Schulleiters unter Datenschutzgesichtspunkten. (5 Punkte)

Aufgabe 2 - Objektorientierte Modellierung · Objektorientierte Modellierung mit Implementationsdiagrammen

Aufgabenstellung: Evakuierungskonzept für den Zoo „Tweety’s Home“

Im Zoo „Tweety’s Home“ stehen Renovierungsarbeiten an. In diesem Zusammenhang soll auch ein Konzept entwickelt werden, mit dem die Besucherinnen und Besucher im Notfall evakuiert werden können. Der Zoo setzt sich aus mehreren Attraktionen zusammen, zwischen denen Wege verlaufen. Jede Attraktion darf nur von einer bestimmten Höchstzahl an Gästen gleichzeitig besucht werden. Da die Wege zwischen den Attraktionen unterschiedlich breit sind, können sich darauf pro Minute unterschiedlich viele Gäste von einer Attraktion zur anderen bewegen. Für den Evakuierungsfall ist für jede Attraktion immer dasjenige Wegstück als bevorzugter Notausgang ( [Notausgangs-Symbol]) gekennzeichnet, über das sich die größtmögliche Anzahl an Gästen pro Minute bewegen kann; nur der Eingang und die Ausgänge verfügen nicht über diese Markierung.

Abbildung 1 zeigt beispielsweise:

Ein-/Ausgang und Spielplatz sind über einen großzügigen Weg verbunden, über den jeweils bis zu 500 Personen pro Minute in jede der beiden möglichen Richtungen zwischen diesen Attraktionen wechseln können.

Für das Delfinarium sind maximal 2000 Gäste zur gleichen Zeit vorgesehen.

Im Evakuierungsfall sollen sich die Gäste des Ziegen-Geheges auf den Weg zum Esel-Gehege begeben.

Eine Softwarefirma hat schon für andere (Freizeit-)Parks eine Software zur Steuerung der Besucherströme programmiert. Es soll geprüft werden, ob sich diese Software für diesen Zoo eignet. Die Firma legt dazu einen Ausschnitt aus einem Implementationsdiagramm (Abbildung 2) vor. Eine Dokumentation der verwendeten Klassen findet sich im Anhang.

Notfall-Räumung einzelner Attraktionen

Ein Teil des Evakuierungskonzepts des Zoos beschäftigt sich mit der Notfall-Räumung einzelner Attraktionen. In einem solchen Fall kann mit einer Attraktion wie folgt verfahren werden:

Eine Attraktion...

wird geräumt: Alle Gäste, die sich an dieser Attraktion befinden, müssen sie verlassen. Dabei wird für die Simulation festgelegt, dass die Gäste die zur Verfügung stehenden Wege absteigend nach ihrer Kapazität nutzen, also zunächst den markierten Notausgang und als Ausweichmöglichkeit alle anderen Wege in absteigender Reihenfolge ihrer Kapazität. Zu räumende Attraktionen dürfen aber immer noch von Gästen neu betreten werden, wenn die Attraktion auf deren Fluchtweg zum Ausgang des Zoos liegt. Die Gäste aber dürfen dort nicht verbleiben, sondern müssen (wie alle anderen) die Attraktion schnellstmöglich verlassen.

ist gesperrt: Gesperrte Attraktionen werden geräumt und dürfen von niemandem neu betreten werden.

Anhang: Dokumentationen der verwendeten Klassen

Die Klasse Besucherverwaltung

Ein Objekt dieser Klasse verwaltet den Lageplan des Zoos mit seinen Attraktionen und aktueller Anzahl von Besucherinnen und Besuchern.

Ausschnitt aus der Dokumentation der Klasse Besucherverwaltung

Besucherverwaltung()

Eine Besucherverwaltung mit dem aktuellen Lageplan des Zoos, allen Attraktionen und den gegenwärtigen Besucherzahlen wird initialisiert. Alle Attraktionen befinden sich im Normalbetrieb, d. h., sie sind nicht gesperrt und werden nicht geräumt.

Die Klasse Attraktion

Ein Objekt dieser Klasse verwaltet eine Attraktion des Zoos, an der sich Gäste sammeln können, z. B. ein Gehege oder einen besonderen Platz, wie Spielplätze oder Sanitärhäuser.

Ausschnitt aus der Dokumentation der Klasse Attraktion

Attraktion(Graph pLageplan, String pID, int pMaxBesucherzahl, int pAktBesucherzahl)

Eine Attraktion wird mit den angegebenen Werten initialisiert: befindet sich auf dem durch pLageplan angegebenen Lageplan; bekommt die interne ID pID; kann maximal pMaxBesucherzahl Gäste zur gleichen Zeit aufnehmen (ist diese als Ausgang anzusehen, wird die Anzahl auf Integer.MAX_VALUE festgelegt); ist aktuell mit pAktBesucherzahl besetzt.

int gibMaxBesucherzahl()

Die maximale Anzahl der Besucherinnen und Besucher, die diese Attraktion gleichzeitig betreten dürfen, wird zurückgegeben.

int gibAktBesucherzahl()

Die aktuelle Anzahl an Besucherinnen und Besuchern dieser Attraktion wird zurückgegeben.

void setzeAktBesucherzahl(int pAktBesucherzahl)

Die aktuelle Anzahl der Besucherinnen und Besucher dieser Attraktion wird auf den Wert pAktBesucherzahl gesetzt.

boolean istGesperrt()

Wenn diese Attraktion zum Zeitpunkt des Methodenaufrufs gesperrt ist, wird true zurückgegeben, ansonsten false. Ist die Attraktion gesperrt, darf sie nicht mehr betreten werden und wird so schnell wie möglich geräumt.

void setzeIstGesperrt(boolean pIstGesperrt)

Der Sperrstatus wird auf den Wert gesetzt. Hat pIstGesperrt den Wert true, wird die Attraktion gleichzeitig als „zu räumen“ markiert. Hat pIstGesperrt den Wert false, wird der Räumungsstatus nicht verändert.

boolean wirdGeraeumt()

Wenn diese Attraktion geräumt werden muss, wird true zurückgegeben, ansonsten false.

void setzeWirdGeraeumt(boolean pWirdGeraeumt)

Der Räumungsstatus dieser Attraktion wird auf den Wert von pWirdGeraeumt gesetzt.

int ermittleMaxAbgabe(Attraktion pNachbar)

Ermittelt die maximale Anzahl an Besucherinnen und Besuchern, die von dieser Attraktion aktuell an die durch pNachbar angegebene Nachbarattraktion abgegeben werden können. Falls pNachbar nicht auf eine Nachbarattraktion verweist, liefert die Methode -1 zurück.

List<Attraktion> wasLiefereIch()

Diese Methode wird im Rahmen von Aufgabenteil c) analysiert.

Die Klasse Graph

Die Klasse Graph stellt einen ungerichteten, kantengewichteten Graphen dar.

Dokumentation der Klasse Graph

Graph()

Ein leerer Graph wird erstellt.

void addVertex(Vertex pVertex)

Fügt den Knoten pVertex ein, sofern es noch keinen Knoten mit derselben ID gibt und pVertex eine ID ungleich null hat.

void addEdge(Edge pEdge)

Fügt die Kante pEdge ein, sofern beide Knoten im Graphen enthalten, nicht identisch sind und noch keine Kante zwischen beiden existiert.

void removeVertex(Vertex pVertex)

Entfernt den Knoten pVertex und löscht alle Kanten, die mit ihm inzident sind.

void removeEdge(Edge pEdge)

Entfernt die Kante pEdge aus dem Graphen.

Vertex getVertex(String pID)

Liefert das Knotenobjekt mit pID als ID oder null.

List<Vertex> getVertices()

Liefert eine neue Liste aller Knotenobjekte vom Typ List<Vertex>.

List<Vertex> getNeighbours(Vertex pVertex)

Liefert alle Nachbarn des Knotens pVertex als neue Liste vom Typ List<Vertex>.

List<Edge> getEdges()

Liefert eine neue Liste aller Kantenobjekte vom Typ List<Edge>.

List<Edge> getEdges(Vertex pVertex)

Liefert eine neue Liste aller inzidenten Kanten zum Knoten pVertex.

Edge getEdge(Vertex pVertex, Vertex pAnotherVertex)

Liefert die Kante, welche die Knoten pVertex und pAnotherVertex verbindet, oder null.

void setAllVertexMarks(boolean pMark)

Setzt die Markierungen aller Knoten des Graphen auf den Wert pMark.

boolean allVerticesMarked()

Liefert true, wenn die Markierungen aller Knoten des Graphen den Wert true haben, ansonsten false.

void setAllEdgeMarks(boolean pMark)

Setzt die Markierungen aller Kanten des Graphen auf den Wert pMark.

boolean allEdgesMarked()

Liefert true, wenn die Markierungen aller Kanten des Graphen den Wert true haben, ansonsten false.

boolean isEmpty()

Liefert true, wenn der Graph keine Knoten enthält, ansonsten false.

Die Klassen Vertex, Edge und List<ContentType>

Klasse Vertex

Vertex(String pID): Erstellt neuen Knoten mit ID pID, Markierung false.

String getID(): Liefert die ID des Knotens.

void setMark(boolean pMark): Setzt Markierung des Knotens.

boolean isMarked(): Liefert Markierungsstatus.

Klasse Edge

Edge(Vertex pVertex, Vertex pAnotherVertex, double pWeight): Verbindet zwei Knoten mit Kantengewicht.

void setWeight(double pWeight) / double getWeight(): Setzt bzw. liefert das Gewicht.

Vertex[] getVertices(): Liefert Feld der beiden inzidenten Knoten (Index 0 und 1).

void setMark(boolean pMark) / boolean isMarked(): Markierungsverwaltung der Kante.

Generische Klasse List<ContentType>

List(), boolean isEmpty(), boolean hasAccess(), void next(), void toFirst(), void toLast(), ContentType getContent(), void setContent(ContentType pContent), void append(ContentType pContent), void insert(ContentType pContent), void concat(List<ContentType> pList), void remove().

b)

Erläutern Sie, wie die Klassen Besucherverwaltung, Attraktion, Graph und Vertex in dem in Abbildung 2 dargestellten Ausschnitt der Modellierung miteinander in Beziehung stehen.

Begründen Sie, weshalb es zweckmäßig ist, dass jedes Objekt der Klasse Attraktion in der vorliegenden Modellierung auf ein Objekt der Klasse Graph zugreifen kann.

(6 + 3 Punkte)

Aufgabe 2 - Graphen und Graphenalgorithmen · Graphen und Graphenalgorithmen (LK)

Aufgabenstellung: Evakuierungskonzept für den Zoo „Tweety’s Home“

Im Zoo „Tweety’s Home“ stehen Renovierungsarbeiten an. In diesem Zusammenhang soll auch ein Konzept entwickelt werden, mit dem die Besucherinnen und Besucher im Notfall evakuiert werden können. Der Zoo setzt sich aus mehreren Attraktionen zusammen, zwischen denen Wege verlaufen. Jede Attraktion darf nur von einer bestimmten Höchstzahl an Gästen gleichzeitig besucht werden. Da die Wege zwischen den Attraktionen unterschiedlich breit sind, können sich darauf pro Minute unterschiedlich viele Gäste von einer Attraktion zur anderen bewegen. Für den Evakuierungsfall ist für jede Attraktion immer dasjenige Wegstück als bevorzugter Notausgang ( [Notausgangs-Symbol]) gekennzeichnet, über das sich die größtmögliche Anzahl an Gästen pro Minute bewegen kann; nur der Eingang und die Ausgänge verfügen nicht über diese Markierung.

Abbildung 1 zeigt beispielsweise:

Ein-/Ausgang und Spielplatz sind über einen großzügigen Weg verbunden, über den jeweils bis zu 500 Personen pro Minute in jede der beiden möglichen Richtungen zwischen diesen Attraktionen wechseln können.

Für das Delfinarium sind maximal 2000 Gäste zur gleichen Zeit vorgesehen.

Im Evakuierungsfall sollen sich die Gäste des Ziegen-Geheges auf den Weg zum Esel-Gehege begeben.

Eine Softwarefirma hat schon für andere (Freizeit-)Parks eine Software zur Steuerung der Besucherströme programmiert. Es soll geprüft werden, ob sich diese Software für diesen Zoo eignet. Die Firma legt dazu einen Ausschnitt aus einem Implementationsdiagramm (Abbildung 2) vor. Eine Dokumentation der verwendeten Klassen findet sich im Anhang.

Notfall-Räumung einzelner Attraktionen

Ein Teil des Evakuierungskonzepts des Zoos beschäftigt sich mit der Notfall-Räumung einzelner Attraktionen. In einem solchen Fall kann mit einer Attraktion wie folgt verfahren werden:

Eine Attraktion...

wird geräumt: Alle Gäste, die sich an dieser Attraktion befinden, müssen sie verlassen. Dabei wird für die Simulation festgelegt, dass die Gäste die zur Verfügung stehenden Wege absteigend nach ihrer Kapazität nutzen, also zunächst den markierten Notausgang und als Ausweichmöglichkeit alle anderen Wege in absteigender Reihenfolge ihrer Kapazität. Zu räumende Attraktionen dürfen aber immer noch von Gästen neu betreten werden, wenn die Attraktion auf deren Fluchtweg zum Ausgang des Zoos liegt. Die Gäste aber dürfen dort nicht verbleiben, sondern müssen (wie alle anderen) die Attraktion schnellstmöglich verlassen.

ist gesperrt: Gesperrte Attraktionen werden geräumt und dürfen von niemandem neu betreten werden.

Anhang: Dokumentationen der verwendeten Klassen

Die Klasse Besucherverwaltung

Ein Objekt dieser Klasse verwaltet den Lageplan des Zoos mit seinen Attraktionen und aktueller Anzahl von Besucherinnen und Besuchern.

Ausschnitt aus der Dokumentation der Klasse Besucherverwaltung

Besucherverwaltung()

Eine Besucherverwaltung mit dem aktuellen Lageplan des Zoos, allen Attraktionen und den gegenwärtigen Besucherzahlen wird initialisiert. Alle Attraktionen befinden sich im Normalbetrieb, d. h., sie sind nicht gesperrt und werden nicht geräumt.

Die Klasse Attraktion

Ein Objekt dieser Klasse verwaltet eine Attraktion des Zoos, an der sich Gäste sammeln können, z. B. ein Gehege oder einen besonderen Platz, wie Spielplätze oder Sanitärhäuser.

Ausschnitt aus der Dokumentation der Klasse Attraktion

Attraktion(Graph pLageplan, String pID, int pMaxBesucherzahl, int pAktBesucherzahl)

Eine Attraktion wird mit den angegebenen Werten initialisiert: befindet sich auf dem durch pLageplan angegebenen Lageplan; bekommt die interne ID pID; kann maximal pMaxBesucherzahl Gäste zur gleichen Zeit aufnehmen (ist diese als Ausgang anzusehen, wird die Anzahl auf Integer.MAX_VALUE festgelegt); ist aktuell mit pAktBesucherzahl besetzt.

int gibMaxBesucherzahl()

Die maximale Anzahl der Besucherinnen und Besucher, die diese Attraktion gleichzeitig betreten dürfen, wird zurückgegeben.

int gibAktBesucherzahl()

Die aktuelle Anzahl an Besucherinnen und Besuchern dieser Attraktion wird zurückgegeben.

void setzeAktBesucherzahl(int pAktBesucherzahl)

Die aktuelle Anzahl der Besucherinnen und Besucher dieser Attraktion wird auf den Wert pAktBesucherzahl gesetzt.

boolean istGesperrt()

Wenn diese Attraktion zum Zeitpunkt des Methodenaufrufs gesperrt ist, wird true zurückgegeben, ansonsten false. Ist die Attraktion gesperrt, darf sie nicht mehr betreten werden und wird so schnell wie möglich geräumt.

void setzeIstGesperrt(boolean pIstGesperrt)

Der Sperrstatus wird auf den Wert gesetzt. Hat pIstGesperrt den Wert true, wird die Attraktion gleichzeitig als „zu räumen“ markiert. Hat pIstGesperrt den Wert false, wird der Räumungsstatus nicht verändert.

boolean wirdGeraeumt()

Wenn diese Attraktion geräumt werden muss, wird true zurückgegeben, ansonsten false.

void setzeWirdGeraeumt(boolean pWirdGeraeumt)

Der Räumungsstatus dieser Attraktion wird auf den Wert von pWirdGeraeumt gesetzt.

int ermittleMaxAbgabe(Attraktion pNachbar)

Ermittelt die maximale Anzahl an Besucherinnen und Besuchern, die von dieser Attraktion aktuell an die durch pNachbar angegebene Nachbarattraktion abgegeben werden können. Falls pNachbar nicht auf eine Nachbarattraktion verweist, liefert die Methode -1 zurück.

List<Attraktion> wasLiefereIch()

Diese Methode wird im Rahmen von Aufgabenteil c) analysiert.

Die Klasse Graph

Die Klasse Graph stellt einen ungerichteten, kantengewichteten Graphen dar.

Dokumentation der Klasse Graph

Graph()

Ein leerer Graph wird erstellt.

void addVertex(Vertex pVertex)

Fügt den Knoten pVertex ein, sofern es noch keinen Knoten mit derselben ID gibt und pVertex eine ID ungleich null hat.

void addEdge(Edge pEdge)

Fügt die Kante pEdge ein, sofern beide Knoten im Graphen enthalten, nicht identisch sind und noch keine Kante zwischen beiden existiert.

void removeVertex(Vertex pVertex)

Entfernt den Knoten pVertex und löscht alle Kanten, die mit ihm inzident sind.

void removeEdge(Edge pEdge)

Entfernt die Kante pEdge aus dem Graphen.

Vertex getVertex(String pID)

Liefert das Knotenobjekt mit pID als ID oder null.

List<Vertex> getVertices()

Liefert eine neue Liste aller Knotenobjekte vom Typ List<Vertex>.

List<Vertex> getNeighbours(Vertex pVertex)

Liefert alle Nachbarn des Knotens pVertex als neue Liste vom Typ List<Vertex>.

List<Edge> getEdges()

Liefert eine neue Liste aller Kantenobjekte vom Typ List<Edge>.

List<Edge> getEdges(Vertex pVertex)

Liefert eine neue Liste aller inzidenten Kanten zum Knoten pVertex.

Edge getEdge(Vertex pVertex, Vertex pAnotherVertex)

Liefert die Kante, welche die Knoten pVertex und pAnotherVertex verbindet, oder null.

void setAllVertexMarks(boolean pMark)

Setzt die Markierungen aller Knoten des Graphen auf den Wert pMark.

boolean allVerticesMarked()

Liefert true, wenn die Markierungen aller Knoten des Graphen den Wert true haben, ansonsten false.

void setAllEdgeMarks(boolean pMark)

Setzt die Markierungen aller Kanten des Graphen auf den Wert pMark.

boolean allEdgesMarked()

Liefert true, wenn die Markierungen aller Kanten des Graphen den Wert true haben, ansonsten false.

boolean isEmpty()

Liefert true, wenn der Graph keine Knoten enthält, ansonsten false.

Die Klassen Vertex, Edge und List<ContentType>

Klasse Vertex

Vertex(String pID): Erstellt neuen Knoten mit ID pID, Markierung false.

String getID(): Liefert die ID des Knotens.

void setMark(boolean pMark): Setzt Markierung des Knotens.

boolean isMarked(): Liefert Markierungsstatus.

Klasse Edge

Edge(Vertex pVertex, Vertex pAnotherVertex, double pWeight): Verbindet zwei Knoten mit Kantengewicht.

void setWeight(double pWeight) / double getWeight(): Setzt bzw. liefert das Gewicht.

Vertex[] getVertices(): Liefert Feld der beiden inzidenten Knoten (Index 0 und 1).

void setMark(boolean pMark) / boolean isMarked(): Markierungsverwaltung der Kante.

Generische Klasse List<ContentType>

List(), boolean isEmpty(), boolean hasAccess(), void next(), void toFirst(), void toLast(), ContentType getContent(), void setContent(ContentType pContent), void append(ContentType pContent), void insert(ContentType pContent), void concat(List<ContentType> pList), void remove().

Teilaufgabe a)

Der Zoo soll um eine Attraktion Pinguine erweitert werden. Diese Attraktion soll alle folgenden Eigenschaften erfüllen:

Die Attraktion kann maximal 100100 Gäste aufnehmen.

Die neue Attraktion ist durch direkte Wege jeweils mit den Ziegen- und Esel- Attraktionen verbunden.

Von der Ziegen-Attraktion können 3030 Gäste pro Minute zur neuen Attraktion gelangen.

Sollte die neue Attraktion geräumt werden müssen, sollen die Gäste als Fluchtweg zunächst zur Esel-Attraktion gehen.

a.1

Geben Sie zunächst ohne Berücksichtigung der geplanten Erweiterung an, wie viele Gäste höchstens pro Minute aus den benachbarten Attraktionen zusammen zum Delfinarium gelangen können.

a.2

Ergänzen Sie Abbildung 1 um die Attraktion Pinguine und bestimmen Sie dabei eine passende (bzw. die kleinstmögliche) Kapazität für den Weg von den Pinguinen zur Esel-Attraktion.

Hinweis: Es genügt, nur die Abweichungen gegenüber Abbildung 1 zu zeichnen.

Teilaufgabe b)

Ein Softwareunternehmen hat schon für andere (Freizeit-)Parks eine Software zur Steuerung der Besucherströme programmiert. Es stellt dazu einen Ausschnitt eines Implementationsdiagramms (Abbildung 2) bereit.

b.1

Erläutern Sie die Beziehungen zwischen den Klassen Besucherverwaltung, Attraktion, Graph und Vertex in der durch Abbildung 2 gegebenen Teilmodellierung.

b.2

Begründen Sie, weshalb es in der vorliegenden Modellierung sinnvoll ist, dass jedes Objekt der Klasse Attraktion auf ein Objekt der Klasse Graph zugreifen kann.

Teilaufgabe c)

Die Klasse Attraktion enthält die folgende Methode ohne Dokumentation:

public List<Attraktion> wasLiefereIch() {

List<Attraktion> ret = new List<Attraktion>();

List<Vertex> allenachbarn = lageplan.getNeighbours(this);

List<Vertex> nachbarn = new List<Vertex>();

allenachbarn.toFirst();

while (allenachbarn.hasAccess()) {

Attraktion aktN = (Attraktion) allenachbarn.getContent();

if (!aktN.istGesperrt()) {

nachbarn.append(aktN);

}

allenachbarn.next();

}

nachbarn.toFirst();

while (nachbarn.hasAccess()) {

Attraktion aktN = (Attraktion) nachbarn.getContent();

ret.toFirst();

while (ret.hasAccess()

&& lageplan.getEdge(this, aktN).getWeight()

<= lageplan.getEdge(this, ret.getContent()).getWeight()) {

ret.next();

}

if (ret.hasAccess()) {

ret.insert(aktN);

} else {

ret.append(aktN);

}

nachbarn.next();

}

return ret;

}

c.1

Analysieren Sie die Methode und erläutern Sie, wie sie arbeitet.

c.2

Ermitteln Sie schrittweise, was die Methode zurückgibt, wenn sie für das Objekt aufgerufen wird, das in Abbildung 1 die Attraktion Streicheltiere darstellt, und nur diese Attraktion gesperrt ist.

c.3

Erläutern Sie, welchem Zweck die Methode im Sachzusammenhang dient.

Teilaufgabe d)

Wird eine Attraktion geräumt, werden die Gäste in benachbarte Attraktionen gebracht. Die Methode ermittleMaxAbgabe der Klasse Attraktion soll ermitteln, wie viele Gäste derzeit zu einer gewählten Nachbarattraktion wechseln und dort untergebracht werden können. Ihr Methodenkopf lautet:

public int ermittleMaxAbgabe(Attraktion pNachbar)

Falls pNachbar keine benachbarte Attraktion bezeichnet, soll die Methode den Fehlerwert -1 zurückgeben.

d.1

Entwickeln Sie für diese Methode einen algorithmischen Lösungsansatz.

d.2

Implementieren Sie diese Methode in Java:

public int ermittleMaxAbgabe(Attraktion pNachbar)

Teilaufgabe e)

Bei einem schweren Notfall können mehrere Attraktionen gleichzeitig Alarm melden. Für eine schrittweise Räumung wird der Algorithmus aus Abbildung 3 vorgeschlagen:

Der Algorithmus soll nun am ursprünglichen Lageplan aus Abbildung 1 betrachtet werden.

e.1

Analysieren und erläutern Sie den Algorithmus im Sachzusammenhang.

e.2

Beurteilen Sie den Algorithmus im Sachzusammenhang anhand der folgenden Szenarien:

i) Alarm wird von den Attraktionen Streicheltiere, Ziegen und Esel gemeldet.

ii) Alarm wird von den Attraktionen Streicheltiere, Spielplatz, Delfinarium und Esel gemeldet.

Aufgabe 3 - Datenbankmodellierung und Normalisier… · Datenbankmodellierung und Normalisierung

Aufgabenstellung:

Weil Gäste Restaurants meist subjektiv beurteilen, plant der Projektkurs „Gastro-Informatik“ ein Bewertungssystem, in dem eine professionelle Gutachterin oder ein professioneller Gutachter Speisequalität, Servicequalität und Hygienezustand auf einer Skala von 0 bis 10 einstuft, wobei 10 die beste Note ist.

Die anfallenden Daten sollen in einer relationalen Datenbank verwaltet werden, die auf der folgenden Teilmodellierung beruht:

Das Datenbankschema in Abbildung 2 überträgt die Teilmodellierung aus Abbildung 1 in eine relationale Datenbank und wird im Weiteren genauer untersucht. Die Anlage enthält Beispieldaten zu diesem Schema.

Anlage:

Ausschnitt aus den Beispieldaten zum Datenbankschema aus Abbildung 2

Gutachter

ID

Vorname

Nachname

1 · Ada · Lovelace

2 · John · Von Neumann

3 · Alan · Turing

4 · Konrad · Zuse

5 · Tim · Berners-Lee

bewertet

GutachterID

RestaurantID

Speisequalitaet

Servicequalitaet

Hygienezustand

1 · 2 · 7 · 8 · 6

4 · 3 · 1 · 8 · 10

4 · 2 · 8 · 5 · 5

3 · 3 · 10 · 7 · 8

2 · 2 · 5 · 8 · 4

1 · 1 · 8 · 9 · 7

Restaurant

ID

Name

PLZ

Ortsname

1 · Meisterpizza · 44269 · Dortmund

2 · Sushi4Friends · 52525 · Heinsberg

3 · Veggie-Haus · 31137 · Hildesheim

4 · Der Grieche · 44135 · Dortmund

5 · Burgerhaus · 52525 · Waldfeucht

Ort

PLZ

Name

31137 · Hildesheim

44135 · Dortmund

44269 · Dortmund

52525 · Heinsberg

52525 · Waldfeucht

Teilaufgabe a)

Beschreiben Sie die Teilmodellierung, die Abbildung 1 in Form eines Entity-Relationship-Diagramms zeigt.

Erläutern Sie die Beziehungstypen des Entity-Relationship-Diagramms in Abbildung 1 einschließlich ihrer Kardinalitäten bezogen auf den Sachkontext.

Erläutern Sie, auf welche Weise der 1:n-Beziehungstyp befindetSichIn sowie der n:m-Beziehungstyp bewertet des Entity-Relationship-Modells aus Abbildung 1 im Datenbankschema in Abbildung 2 realisiert wurden.

[3 + 4 + 4 Punkte]

Teilaufgabe d)

Die Erprobung des Restaurantbewertungssystems in der Praxis hat ergeben, dass folgende Punkte angepasst werden müssen:

i. Eine Gutachterin bzw. ein Gutachter soll das gleiche Restaurant nach einigen Tagen oder Wochen erneut bewerten können. Außerdem soll für jede Bewertung die Möglichkeit bestehen, zusätzlich einen freien Bewertungstext eintragen zu können.

ii. Jede Gutachterin bzw. jeder Gutachter soll Wünsche bezüglich ihres bzw. seines Einsatzortes äußern dürfen. Für jede Gutachterin bzw. jeden Gutachter sollen daher mehrere bevorzugte Einsatzorte gespeichert werden.

iii. In jedem Jahr sollen die besten drei Restaurants in den Kategorien Speisequalität, Servicequalität und Hygienezustand besonders ausgezeichnet werden. Die Information, welches Restaurant in welchem Jahr in welcher Bewertungskategorie einen der ersten drei Plätze belegt hat, soll ebenfalls verwaltet werden.

Modellieren Sie eine Erweiterung des Datenbankschemas aus Abbildung 2, sodass der neue Entwurf auch die beschriebenen Aspekte abdeckt.

Erläutern Sie, auf welche Weise Ihr Modell die Anforderungen erfüllt, und begründen Sie die gewählten Primärschlüssel, sofern sich deren Zusammensetzung ändert oder neue Relationenschemata entstehen.

Hinweis: Unveränderte Relationenschemata brauchen nicht aufgeführt zu werden.

[7 + 6 Punkte]

Teilaufgabe e)

Ein Praktikant regt an, anstelle des Datenbankschemas aus Abbildung 2 seinen Entwurf aus Abbildung 3 zu verwenden.

Der Praktikant ist davon überzeugt, dass man mit seinem Vorschlag Speicherplatz einsparen und die Übersichtlichkeit erhöhen könne. Man müsse schließlich deutlich weniger Attribute verwalten, weil zusätzliche Fremdschlüssel entfallen. Das Datenbankschema in Abbildung 3 sei zudem einfacher zu lesen und beinhalte im Vergleich zum Datenbankschema in Abbildung 2 keine nennenswerten Nachteile.

Beurteilen Sie den Vorschlag des Praktikanten hinsichtlich seiner genannten Argumente und unter Einbeziehung der Normalformen.

[6 Punkte]

Aufgabe 3 - SQL-Abfragen · SQL-Abfragen

Aufgabenstellung:

Weil Gäste Restaurants meist subjektiv beurteilen, plant der Projektkurs „Gastro-Informatik“ ein Bewertungssystem, in dem eine professionelle Gutachterin oder ein professioneller Gutachter Speisequalität, Servicequalität und Hygienezustand auf einer Skala von 0 bis 10 einstuft, wobei 10 die beste Note ist.

Die anfallenden Daten sollen in einer relationalen Datenbank verwaltet werden, die auf der folgenden Teilmodellierung beruht:

Das Datenbankschema in Abbildung 2 überträgt die Teilmodellierung aus Abbildung 1 in eine relationale Datenbank und wird im Weiteren genauer untersucht. Die Anlage enthält Beispieldaten zu diesem Schema.

Anlage:

Ausschnitt aus den Beispieldaten zum Datenbankschema aus Abbildung 2

Gutachter

ID

Vorname

Nachname

1 · Ada · Lovelace

2 · John · Von Neumann

3 · Alan · Turing

4 · Konrad · Zuse

5 · Tim · Berners-Lee

bewertet

GutachterID

RestaurantID

Speisequalitaet

Servicequalitaet

Hygienezustand

1 · 2 · 7 · 8 · 6

4 · 3 · 1 · 8 · 10

4 · 2 · 8 · 5 · 5

3 · 3 · 10 · 7 · 8

2 · 2 · 5 · 8 · 4

1 · 1 · 8 · 9 · 7

Restaurant

ID

Name

PLZ

Ortsname

1 · Meisterpizza · 44269 · Dortmund

2 · Sushi4Friends · 52525 · Heinsberg

3 · Veggie-Haus · 31137 · Hildesheim

4 · Der Grieche · 44135 · Dortmund

5 · Burgerhaus · 52525 · Waldfeucht

Ort

PLZ

Name

31137 · Hildesheim

44135 · Dortmund

44269 · Dortmund

52525 · Heinsberg

52525 · Waldfeucht

Teilaufgabe b)

Mithilfe der im Anhang beschriebenen Datenbank sollen die folgenden Abfragen umgesetzt werden:

i.

Ermittelt werden sollen die Namen aller Restaurants, deren PLZ zwischen 44100 und 44300 liegt (Grenzen eingeschlossen). Die Ausgabe soll aufsteigend nach dem Restaurantnamen geordnet sein. [3 Punkte]

ii.

Ermittelt werden sollen alle Restaurants, für die bisher keine Bewertung vorliegt. Auszugeben sind jeweils der Restaurantname, die PLZ und der Ortsname. [4 Punkte]

iii.

Ermittelt werden soll, wie viele Restaurants es je PLZ gibt. Auch PLZ ohne Restaurant müssen im Ergebnis erscheinen. Die Ausgabe soll nach der Restaurantanzahl absteigend geordnet sein. [5 Punkte]

Teilaufgabe c)

Gegeben ist die folgende SQL-Anweisung:

1 SELECT Temp.Ortsname, MAX(Temp.d) AS Max, MIN(Temp.d) AS Min

2 FROM (

3 SELECT Restaurant.ID, Restaurant.Ortsname,

4 AVG(bewertet.Speisequalitaet) AS d

5 FROM bewertet

6 INNER JOIN Restaurant

7 ON bewertet.RestaurantID = Restaurant.ID

8 GROUP BY Restaurant.ID

9) AS Temp

10 GROUP BY Temp.Ortsname

1.

Analysieren und erläutern Sie erst die Unterabfrage (Zeilen 3 bis 8) und danach die vollständige SQL-Anweisung. [6 Punkte]

2.

Erläutern Sie, welche Information die vollständige SQL-Anweisung im Sachzusammenhang liefert. [2 Punkte]

Aufgabe 4 - Endliche Automaten · Endliche Automaten

Sachkontext: Signalprotokolle im SETI-Projekt

Radioteleskope gehören zu den zentralen Instrumenten der heutigen Astronomie. Mithilfe großer Antennen erfassen sie Signale im Frequenzbereich von 0.01 GHz und 100.00 GHz und stellen diese Daten vielen Forschungsprojekten zur Verfügung. Eines davon ist das SETI-Projekt (Search for Extraterrestrial Intelligence), das untersucht, ob einige der empfangenen Radiosignale von außerirdischen Zivilisationen stammen könnten, die Kontakt aufnehmen wollen.

So könnte ein einfaches Frequenz-Signalprotokoll aussehen:

43.22;0.10;3.21;1.53;14.22 Das Protokoll entsteht, indem einmal pro Sekunde ein neuer Eintrag mit dem jeweils stärksten Signal durch ein Semikolon abgetrennt ergänzt wird. Wird ein Signal empfangen, so wird die Frequenz auf zwei Nachkommastellen genau angefügt. Wird kein Signal empfangen, wird 0.00 angefügt. Signalprotokolle können prinzipiell beliebig lang sein.

Beim SETI-Projekt sucht man in Signalprotokollen in erster Linie nach Frequenzen zwischen einschließlich 1.42 GHz und einschließlich 1.66 GHz, dem sogenannten Wasserloch. In diesem Frequenzbereich existieren besonders wenig störende natürliche Signale, so dass man davon ausgeht, dass eine außerirdische Zivilisation diesen Frequenzbereich zur Kontaktaufnahme nutzen würde.

Obwohl der Wasserloch-Frequenzbereich relativ wenig natürliche Störquellen beinhaltet, kommt es immer wieder zu künstlichen Störsignalen, die in der Umgebung des Radioteleskops durch technische Geräte (z. B. Mikrowellenöfen) entstehen. Im Verhältnis zu Signalen, die aus großer Entfernung zu uns kommen, sind diese Störsignale meist sehr energiereich, so dass man sie oft anhand der Signalstärke identifizieren kann.

Beim SETI-Projekt beschließt man daher, in Zukunft mit einem erweiterten Signalprotokoll zu arbeiten, in dem neben der Frequenz auch die Signalstärke verzeichnet ist. Ein solches erweitertes Signalprotokoll könnte wie folgt aussehen:

(43.22:2);(0.10:1);(3.21:4);(0.00:0);(1.53:b);(14.22:9) Hinter jedem Frequenzeintrag steht nun durch einen Doppelpunkt abgetrennt die Stärke des Signals in den Stufen

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f

wobei 1 für ein sehr schwaches und f für ein sehr starkes Signal steht. Die Signalstärke 0 wird eingetragen, wenn kein Signal aufgefangen wurde. Darüber hinaus wird jeder so erweiterte Frequenzeintrag in Klammern gesetzt.

Anhang: Dokumentation der Klassen

Die Klasse Protokollpruefer

Ein Objekt der Klasse Protokollpruefer wird verwendet, um erweiterte Signalprotokolle auf eventuelle Kontaktversuche von außerirdischen Zivilisationen zu überprüfen.

Dokumentation der Klasse Protokollpruefer Protokollpruefer()

Das Objekt der Klasse Protokollpruefer wird initialisiert.

List<Signal> ermittleMoeglicheKontakte(List<Signal> pProtokoll)

Die Methode liefert eine Liste aller Signaleinträge aus dem Signalprotokoll pProtokoll, deren Frequenzen zwischen einschließlich 1.42 GHz und einschließlich 1.66 GHz liegen und die Signalstärke 1 oder 2 haben.

Die Klasse Signal

Ein Objekt der Klasse Signal speichert einen einzelnen Signaleintrag bestehend aus einer Signalfrequenz und einer Signalstärke.

Dokumentation der Klasse Signal Signal(double pFrequenz, char pStaerke)

Das Objekt der Klasse Signal wird mit pFrequenz als Signalfrequenz und pStaerke als Signalstärke initialisiert.

double gibFrequenz()

Die Methode liefert die Signalfrequenz des Eintrags.

char gibStaerke()

Die Methode liefert die Signalstärke des Eintrags.

Die generische Klasse List

Objekte der generischen Klasse List verwalten beliebig viele, linear angeordnete Objekte vom Typ ContentType. Auf höchstens ein Listenobjekt, aktuelles Objekt genannt, kann jeweils zugegriffen werden. Wenn eine Liste leer ist, vollständig durchlaufen wurde oder das aktuelle Objekt am Ende der Liste gelöscht wurde, gibt es kein aktuelles Objekt. Das erste oder das letzte Objekt einer Liste kann durch einen Auftrag zum aktuellen Objekt gemacht werden. Außerdem kann das dem aktuellen Objekt folgende Listenobjekt zum neuen aktuellen Objekt werden.

Das aktuelle Objekt kann gelesen, verändert oder gelöscht werden. Außerdem kann vor dem aktuellen Objekt ein Listenobjekt eingefügt werden.

Dokumentation der Klasse List<ContentType> List()

Eine leere Liste wird erzeugt.

boolean isEmpty()

Die Anfrage liefert den Wert true, wenn die Liste keine Objekte enthält, sonst liefert sie den Wert false.

boolean hasAccess()

Die Anfrage liefert den Wert true, wenn es ein aktuelles Objekt gibt, sonst liefert sie den Wert false.

void next()

Falls die Liste nicht leer ist, es ein aktuelles Objekt gibt und dieses nicht das letzte Objekt der Liste ist, wird das dem aktuellen Objekt in der Liste folgende Objekt zum aktuellen Objekt, andernfalls gibt es nach Ausführung des Auftrags kein aktuelles Objekt, d. h., hasAccess() liefert den Wert false.

void toFirst()

Falls die Liste nicht leer ist, wird das erste Objekt der Liste aktuelles Objekt. Ist die Liste leer, geschieht nichts.

void toLast()

Falls die Liste nicht leer ist, wird das letzte Objekt der Liste aktuelles Objekt. Ist die Liste leer, geschieht nichts.

ContentType getContent()

Falls es ein aktuelles Objekt gibt (hasAccess() == true), wird das aktuelle Objekt zurückgegeben. Andernfalls (hasAccess() == false) gibt die Anfrage den Wert null zurück.

void setContent(ContentType pContent)

Falls es ein aktuelles Objekt gibt (hasAccess() == true) und pContent ungleich null ist, wird das aktuelle Objekt durch pContent ersetzt. Sonst bleibt die Liste unverändert.

void append(ContentType pContent)

Ein neues Objekt pContent wird am Ende der Liste eingefügt. Das aktuelle Objekt bleibt unverändert. Wenn die Liste leer ist, wird das Objekt pContent in die Liste eingefügt und es gibt weiterhin kein aktuelles Objekt (hasAccess() == false). Falls pContent gleich null ist, bleibt die Liste unverändert.

void insert(ContentType pContent)

Falls es ein aktuelles Objekt gibt (hasAccess() == true), wird ein neues Objekt pContent vor dem aktuellen Objekt in die Liste eingefügt. Das aktuelle Objekt bleibt unverändert. Falls die Liste leer ist und es somit kein aktuelles Objekt gibt (hasAccess() == false), wird pContent in die Liste eingefügt und es gibt weiterhin kein aktuelles Objekt. Falls es kein aktuelles Objekt gibt (hasAccess() == false) und die Liste nicht leer ist oder pContent == null ist, bleibt die Liste unverändert.

void concat(List<ContentType> pList)

Die Liste pList wird an die Liste angehängt. Anschließend wird pList eine leere Liste. Das aktuelle Objekt bleibt unverändert. Falls es sich bei der Liste und pList um dasselbe Objekt handelt, pList == null oder eine leere Liste ist, bleibt die Liste unverändert.

void remove()

Falls es ein aktuelles Objekt gibt (hasAccess() == true), wird das aktuelle Objekt gelöscht und das Objekt hinter dem gelöschten Objekt wird zum aktuellen Objekt. Wird das Objekt, das am Ende der Liste steht, gelöscht, gibt es kein aktuelles Objekt mehr (hasAccess() == false). Wenn die Liste leer ist oder es kein aktuelles Objekt gibt (hasAccess() == false), bleibt die Liste unverändert.

a)

Wenn Signalprotokolle übertragen werden, treten oft Fehler auf, welche die spätere Auswertung erschweren. Deshalb wird die Korrektheit der Protokolle überprüft. Hierfür dient der Automat A1A_1, dessen Zustandsübergangsdiagramm Abbildung 1 zeigt. Seine Aufgabe erfüllt er allerdings nur zum Teil.

Geben Sie für den Automaten A1A_1 den Startzustand, die Endzustände, das Eingabealphabet und die Zustandsmenge an.

Analysieren Sie den Automaten A1A_1 und erläutern Sie, welchen Aufbau eine Eingabezeichenfolge haben muss, damit sie als fehlerfrei akzeptiert wird.

Ermitteln Sie eine Zeichenfolge, die der Automat A1A_1 akzeptiert, obwohl sie kein korrektes Signalprotokoll ist.

[9 Punkte]

b)

Im SETI-Projekt werden Signalprotokolle vor allem auf Frequenzen von 1.42 GHz1.42\text{ GHz} bis einschließlich 1.66 GHz1.66\text{ GHz} untersucht, das sogenannte Wasserloch (Grenzen eingeschlossen). Da es dort besonders wenige natürliche Störsignale gibt, vermutet man, dass eine außerirdische Zivilisation diesen Bereich für die Kontaktaufnahme wählen würde.

Ein Mitarbeiter hat die Idee, auch für die inhaltliche Auswertung einen Automaten zur Hilfe zu nehmen. Der nichtdeterministische endliche Automat A2A_2 soll von allen einfachen Signalprotokollen diejenigen akzeptieren, in denen mindestens ein Signal im Wasserloch-Frequenzbereich enthalten ist. Die formale Korrektheit des Protokolls kann vorausgesetzt werden, so dass sie vom Automaten A2A_2 nicht überprüft werden muss.

Entwerfen Sie den nichtdeterministischen endlichen Automaten A2A_2 gemäß den genannten Anforderungen.

Begründen Sie, warum Ihr Automat A2A_2 ein nichtdeterministischer endlicher Automat (NEA) ist.

Zeigen Sie, dass das Signalprotokoll 9.01;1.52;0.00 von Ihrem Automaten A2A_2 akzeptiert wird.

[14 Punkte]

Aufgabe 4 - Grammatiken und Kellerautomaten · Grammatiken, Kellerautomaten und Grenzen endlicher Automaten

Sachkontext: Signalprotokolle im SETI-Projekt

Radioteleskope gehören zu den zentralen Instrumenten der heutigen Astronomie. Mithilfe großer Antennen erfassen sie Signale im Frequenzbereich von 0.01 GHz und 100.00 GHz und stellen diese Daten vielen Forschungsprojekten zur Verfügung. Eines davon ist das SETI-Projekt (Search for Extraterrestrial Intelligence), das untersucht, ob einige der empfangenen Radiosignale von außerirdischen Zivilisationen stammen könnten, die Kontakt aufnehmen wollen.

So könnte ein einfaches Frequenz-Signalprotokoll aussehen:

43.22;0.10;3.21;1.53;14.22 Das Protokoll entsteht, indem einmal pro Sekunde ein neuer Eintrag mit dem jeweils stärksten Signal durch ein Semikolon abgetrennt ergänzt wird. Wird ein Signal empfangen, so wird die Frequenz auf zwei Nachkommastellen genau angefügt. Wird kein Signal empfangen, wird 0.00 angefügt. Signalprotokolle können prinzipiell beliebig lang sein.

Beim SETI-Projekt sucht man in Signalprotokollen in erster Linie nach Frequenzen zwischen einschließlich 1.42 GHz und einschließlich 1.66 GHz, dem sogenannten Wasserloch. In diesem Frequenzbereich existieren besonders wenig störende natürliche Signale, so dass man davon ausgeht, dass eine außerirdische Zivilisation diesen Frequenzbereich zur Kontaktaufnahme nutzen würde.

Obwohl der Wasserloch-Frequenzbereich relativ wenig natürliche Störquellen beinhaltet, kommt es immer wieder zu künstlichen Störsignalen, die in der Umgebung des Radioteleskops durch technische Geräte (z. B. Mikrowellenöfen) entstehen. Im Verhältnis zu Signalen, die aus großer Entfernung zu uns kommen, sind diese Störsignale meist sehr energiereich, so dass man sie oft anhand der Signalstärke identifizieren kann.

Beim SETI-Projekt beschließt man daher, in Zukunft mit einem erweiterten Signalprotokoll zu arbeiten, in dem neben der Frequenz auch die Signalstärke verzeichnet ist. Ein solches erweitertes Signalprotokoll könnte wie folgt aussehen:

(43.22:2);(0.10:1);(3.21:4);(0.00:0);(1.53:b);(14.22:9) Hinter jedem Frequenzeintrag steht nun durch einen Doppelpunkt abgetrennt die Stärke des Signals in den Stufen

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f

wobei 1 für ein sehr schwaches und f für ein sehr starkes Signal steht. Die Signalstärke 0 wird eingetragen, wenn kein Signal aufgefangen wurde. Darüber hinaus wird jeder so erweiterte Frequenzeintrag in Klammern gesetzt.

Anhang: Dokumentation der Klassen

Die Klasse Protokollpruefer

Ein Objekt der Klasse Protokollpruefer wird verwendet, um erweiterte Signalprotokolle auf eventuelle Kontaktversuche von außerirdischen Zivilisationen zu überprüfen.

Dokumentation der Klasse Protokollpruefer Protokollpruefer()

Das Objekt der Klasse Protokollpruefer wird initialisiert.

List<Signal> ermittleMoeglicheKontakte(List<Signal> pProtokoll)

Die Methode liefert eine Liste aller Signaleinträge aus dem Signalprotokoll pProtokoll, deren Frequenzen zwischen einschließlich 1.42 GHz und einschließlich 1.66 GHz liegen und die Signalstärke 1 oder 2 haben.

Die Klasse Signal

Ein Objekt der Klasse Signal speichert einen einzelnen Signaleintrag bestehend aus einer Signalfrequenz und einer Signalstärke.

Dokumentation der Klasse Signal Signal(double pFrequenz, char pStaerke)

Das Objekt der Klasse Signal wird mit pFrequenz als Signalfrequenz und pStaerke als Signalstärke initialisiert.

double gibFrequenz()

Die Methode liefert die Signalfrequenz des Eintrags.

char gibStaerke()

Die Methode liefert die Signalstärke des Eintrags.

Die generische Klasse List

Objekte der generischen Klasse List verwalten beliebig viele, linear angeordnete Objekte vom Typ ContentType. Auf höchstens ein Listenobjekt, aktuelles Objekt genannt, kann jeweils zugegriffen werden. Wenn eine Liste leer ist, vollständig durchlaufen wurde oder das aktuelle Objekt am Ende der Liste gelöscht wurde, gibt es kein aktuelles Objekt. Das erste oder das letzte Objekt einer Liste kann durch einen Auftrag zum aktuellen Objekt gemacht werden. Außerdem kann das dem aktuellen Objekt folgende Listenobjekt zum neuen aktuellen Objekt werden.

Das aktuelle Objekt kann gelesen, verändert oder gelöscht werden. Außerdem kann vor dem aktuellen Objekt ein Listenobjekt eingefügt werden.

Dokumentation der Klasse List<ContentType> List()

Eine leere Liste wird erzeugt.

boolean isEmpty()

Die Anfrage liefert den Wert true, wenn die Liste keine Objekte enthält, sonst liefert sie den Wert false.

boolean hasAccess()

Die Anfrage liefert den Wert true, wenn es ein aktuelles Objekt gibt, sonst liefert sie den Wert false.

void next()

Falls die Liste nicht leer ist, es ein aktuelles Objekt gibt und dieses nicht das letzte Objekt der Liste ist, wird das dem aktuellen Objekt in der Liste folgende Objekt zum aktuellen Objekt, andernfalls gibt es nach Ausführung des Auftrags kein aktuelles Objekt, d. h., hasAccess() liefert den Wert false.

void toFirst()

Falls die Liste nicht leer ist, wird das erste Objekt der Liste aktuelles Objekt. Ist die Liste leer, geschieht nichts.

void toLast()

Falls die Liste nicht leer ist, wird das letzte Objekt der Liste aktuelles Objekt. Ist die Liste leer, geschieht nichts.

ContentType getContent()

Falls es ein aktuelles Objekt gibt (hasAccess() == true), wird das aktuelle Objekt zurückgegeben. Andernfalls (hasAccess() == false) gibt die Anfrage den Wert null zurück.

void setContent(ContentType pContent)

Falls es ein aktuelles Objekt gibt (hasAccess() == true) und pContent ungleich null ist, wird das aktuelle Objekt durch pContent ersetzt. Sonst bleibt die Liste unverändert.

void append(ContentType pContent)

Ein neues Objekt pContent wird am Ende der Liste eingefügt. Das aktuelle Objekt bleibt unverändert. Wenn die Liste leer ist, wird das Objekt pContent in die Liste eingefügt und es gibt weiterhin kein aktuelles Objekt (hasAccess() == false). Falls pContent gleich null ist, bleibt die Liste unverändert.

void insert(ContentType pContent)

Falls es ein aktuelles Objekt gibt (hasAccess() == true), wird ein neues Objekt pContent vor dem aktuellen Objekt in die Liste eingefügt. Das aktuelle Objekt bleibt unverändert. Falls die Liste leer ist und es somit kein aktuelles Objekt gibt (hasAccess() == false), wird pContent in die Liste eingefügt und es gibt weiterhin kein aktuelles Objekt. Falls es kein aktuelles Objekt gibt (hasAccess() == false) und die Liste nicht leer ist oder pContent == null ist, bleibt die Liste unverändert.

void concat(List<ContentType> pList)

Die Liste pList wird an die Liste angehängt. Anschließend wird pList eine leere Liste. Das aktuelle Objekt bleibt unverändert. Falls es sich bei der Liste und pList um dasselbe Objekt handelt, pList == null oder eine leere Liste ist, bleibt die Liste unverändert.

void remove()

Falls es ein aktuelles Objekt gibt (hasAccess() == true), wird das aktuelle Objekt gelöscht und das Objekt hinter dem gelöschten Objekt wird zum aktuellen Objekt. Wird das Objekt, das am Ende der Liste steht, gelöscht, gibt es kein aktuelles Objekt mehr (hasAccess() == false). Wenn die Liste leer ist oder es kein aktuelles Objekt gibt (hasAccess() == false), bleibt die Liste unverändert.

Teilaufgabe c)

Die Sprache der erweiterten Signalprotokolle wird durch die nachstehende Grammatik G1G_1 erzeugt.

Startsymbol: SS

Terminalsymbole: {0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,(,),.,:,;}\{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, (,),.,:,;\}

Nichtterminalsymbole: {S,F,I,N,Z,B}\{S, F, I, N, Z, B\}

Produktionen:

S → F:I | F:I;S,

F → (ZN.NN,

I → N) | B),

N → 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9,

Z → &epsilon; | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9,

B → a | b | c | d | e | f

c.1

Erläutern Sie die Produktionen der Grammatik G1G_1. [5 Punkte]

c.2

Begründen Sie, weshalb die Grammatik G1G_1 nicht zu den regulären Grammatiken gehört. [3 Punkte]

c.3

Begründen Sie, weshalb die Sprache, die die Grammatik G1G_1 erzeugt, regulär ist. [4 Punkte]

Teilaufgabe e)

Bald zeigt sich, dass die Signalstärke Störsignale nicht zuverlässig erkennen lässt. Auch Störsignale können schwach sein, und möglicherweise werden Kontaktversuche von Außerirdischen mit sehr hoher Energie gesendet.

Deshalb will das SETI-Projekt künftig anders vorgehen und zusätzlich ein Radioteleskop in Nordafrika nutzen. Wegen der abgelegenen Lage erhofft man sich dort weniger Störsignale.

Um das zu überprüfen, wird ein Protokoll aus Nordafrika, durch ein Ausrufezeichen ( !) abgetrennt, an ein Protokoll aus Europa angefügt. Beide Protokolle müssen genau denselben Zeitraum abdecken.

Beispiel:

3.21;0.00;1.53;14.22 (Europa)

64.22;0.12;1.53;23.11 (Nordafrika)

3.21;0.00;1.53;14.22!64.22;0.12;1.53;23.11 (kombiniert)

Ein Kellerautomat soll nun feststellen, ob der Eintrag 0.00 im Protokoll aus Nordafrika häufiger vorkommt als im Protokoll aus Europa, der afrikanische Standort also &bdquo;ruhiger“ ist.

e)

Beurteilen Sie, ob ein Kellerautomat anhand des kombinierten Protokolls entscheiden kann, ob der nordafrikanische Standort ruhiger ist. [6 Punkte]

Aufgabe 4 - Algorithmen auf Listen · Algorithmen auf Feldern und linearen Listen

Sachkontext: Signalprotokolle im SETI-Projekt

Radioteleskope gehören zu den zentralen Instrumenten der heutigen Astronomie. Mithilfe großer Antennen erfassen sie Signale im Frequenzbereich von 0.01 GHz und 100.00 GHz und stellen diese Daten vielen Forschungsprojekten zur Verfügung. Eines davon ist das SETI-Projekt (Search for Extraterrestrial Intelligence), das untersucht, ob einige der empfangenen Radiosignale von außerirdischen Zivilisationen stammen könnten, die Kontakt aufnehmen wollen.

So könnte ein einfaches Frequenz-Signalprotokoll aussehen:

43.22;0.10;3.21;1.53;14.22 Das Protokoll entsteht, indem einmal pro Sekunde ein neuer Eintrag mit dem jeweils stärksten Signal durch ein Semikolon abgetrennt ergänzt wird. Wird ein Signal empfangen, so wird die Frequenz auf zwei Nachkommastellen genau angefügt. Wird kein Signal empfangen, wird 0.00 angefügt. Signalprotokolle können prinzipiell beliebig lang sein.

Beim SETI-Projekt sucht man in Signalprotokollen in erster Linie nach Frequenzen zwischen einschließlich 1.42 GHz und einschließlich 1.66 GHz, dem sogenannten Wasserloch. In diesem Frequenzbereich existieren besonders wenig störende natürliche Signale, so dass man davon ausgeht, dass eine außerirdische Zivilisation diesen Frequenzbereich zur Kontaktaufnahme nutzen würde.

Obwohl der Wasserloch-Frequenzbereich relativ wenig natürliche Störquellen beinhaltet, kommt es immer wieder zu künstlichen Störsignalen, die in der Umgebung des Radioteleskops durch technische Geräte (z. B. Mikrowellenöfen) entstehen. Im Verhältnis zu Signalen, die aus großer Entfernung zu uns kommen, sind diese Störsignale meist sehr energiereich, so dass man sie oft anhand der Signalstärke identifizieren kann.

Beim SETI-Projekt beschließt man daher, in Zukunft mit einem erweiterten Signalprotokoll zu arbeiten, in dem neben der Frequenz auch die Signalstärke verzeichnet ist. Ein solches erweitertes Signalprotokoll könnte wie folgt aussehen:

(43.22:2);(0.10:1);(3.21:4);(0.00:0);(1.53:b);(14.22:9) Hinter jedem Frequenzeintrag steht nun durch einen Doppelpunkt abgetrennt die Stärke des Signals in den Stufen

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f

wobei 1 für ein sehr schwaches und f für ein sehr starkes Signal steht. Die Signalstärke 0 wird eingetragen, wenn kein Signal aufgefangen wurde. Darüber hinaus wird jeder so erweiterte Frequenzeintrag in Klammern gesetzt.

Anhang: Dokumentation der Klassen

Die Klasse Protokollpruefer

Ein Objekt der Klasse Protokollpruefer wird verwendet, um erweiterte Signalprotokolle auf eventuelle Kontaktversuche von außerirdischen Zivilisationen zu überprüfen.

Dokumentation der Klasse Protokollpruefer Protokollpruefer()

Das Objekt der Klasse Protokollpruefer wird initialisiert.

List<Signal> ermittleMoeglicheKontakte(List<Signal> pProtokoll)

Die Methode liefert eine Liste aller Signaleinträge aus dem Signalprotokoll pProtokoll, deren Frequenzen zwischen einschließlich 1.42 GHz und einschließlich 1.66 GHz liegen und die Signalstärke 1 oder 2 haben.

Die Klasse Signal

Ein Objekt der Klasse Signal speichert einen einzelnen Signaleintrag bestehend aus einer Signalfrequenz und einer Signalstärke.

Dokumentation der Klasse Signal Signal(double pFrequenz, char pStaerke)

Das Objekt der Klasse Signal wird mit pFrequenz als Signalfrequenz und pStaerke als Signalstärke initialisiert.

double gibFrequenz()

Die Methode liefert die Signalfrequenz des Eintrags.

char gibStaerke()

Die Methode liefert die Signalstärke des Eintrags.

Die generische Klasse List

Objekte der generischen Klasse List verwalten beliebig viele, linear angeordnete Objekte vom Typ ContentType. Auf höchstens ein Listenobjekt, aktuelles Objekt genannt, kann jeweils zugegriffen werden. Wenn eine Liste leer ist, vollständig durchlaufen wurde oder das aktuelle Objekt am Ende der Liste gelöscht wurde, gibt es kein aktuelles Objekt. Das erste oder das letzte Objekt einer Liste kann durch einen Auftrag zum aktuellen Objekt gemacht werden. Außerdem kann das dem aktuellen Objekt folgende Listenobjekt zum neuen aktuellen Objekt werden.

Das aktuelle Objekt kann gelesen, verändert oder gelöscht werden. Außerdem kann vor dem aktuellen Objekt ein Listenobjekt eingefügt werden.

Dokumentation der Klasse List<ContentType> List()

Eine leere Liste wird erzeugt.

boolean isEmpty()

Die Anfrage liefert den Wert true, wenn die Liste keine Objekte enthält, sonst liefert sie den Wert false.

boolean hasAccess()

Die Anfrage liefert den Wert true, wenn es ein aktuelles Objekt gibt, sonst liefert sie den Wert false.

void next()

Falls die Liste nicht leer ist, es ein aktuelles Objekt gibt und dieses nicht das letzte Objekt der Liste ist, wird das dem aktuellen Objekt in der Liste folgende Objekt zum aktuellen Objekt, andernfalls gibt es nach Ausführung des Auftrags kein aktuelles Objekt, d. h., hasAccess() liefert den Wert false.

void toFirst()

Falls die Liste nicht leer ist, wird das erste Objekt der Liste aktuelles Objekt. Ist die Liste leer, geschieht nichts.

void toLast()

Falls die Liste nicht leer ist, wird das letzte Objekt der Liste aktuelles Objekt. Ist die Liste leer, geschieht nichts.

ContentType getContent()

Falls es ein aktuelles Objekt gibt (hasAccess() == true), wird das aktuelle Objekt zurückgegeben. Andernfalls (hasAccess() == false) gibt die Anfrage den Wert null zurück.

void setContent(ContentType pContent)

Falls es ein aktuelles Objekt gibt (hasAccess() == true) und pContent ungleich null ist, wird das aktuelle Objekt durch pContent ersetzt. Sonst bleibt die Liste unverändert.

void append(ContentType pContent)

Ein neues Objekt pContent wird am Ende der Liste eingefügt. Das aktuelle Objekt bleibt unverändert. Wenn die Liste leer ist, wird das Objekt pContent in die Liste eingefügt und es gibt weiterhin kein aktuelles Objekt (hasAccess() == false). Falls pContent gleich null ist, bleibt die Liste unverändert.

void insert(ContentType pContent)

Falls es ein aktuelles Objekt gibt (hasAccess() == true), wird ein neues Objekt pContent vor dem aktuellen Objekt in die Liste eingefügt. Das aktuelle Objekt bleibt unverändert. Falls die Liste leer ist und es somit kein aktuelles Objekt gibt (hasAccess() == false), wird pContent in die Liste eingefügt und es gibt weiterhin kein aktuelles Objekt. Falls es kein aktuelles Objekt gibt (hasAccess() == false) und die Liste nicht leer ist oder pContent == null ist, bleibt die Liste unverändert.

void concat(List<ContentType> pList)

Die Liste pList wird an die Liste angehängt. Anschließend wird pList eine leere Liste. Das aktuelle Objekt bleibt unverändert. Falls es sich bei der Liste und pList um dasselbe Objekt handelt, pList == null oder eine leere Liste ist, bleibt die Liste unverändert.

void remove()

Falls es ein aktuelles Objekt gibt (hasAccess() == true), wird das aktuelle Objekt gelöscht und das Objekt hinter dem gelöschten Objekt wird zum aktuellen Objekt. Wird das Objekt, das am Ende der Liste steht, gelöscht, gibt es kein aktuelles Objekt mehr (hasAccess() == false). Wenn die Liste leer ist oder es kein aktuelles Objekt gibt (hasAccess() == false), bleibt die Liste unverändert.

Signale mit zu großer Signalstärke kommen nicht als Kontaktversuch in Frage, deshalb sollen nur schwache Signale im Wasserloch-Frequenzbereich mit den Signalstärken 1 oder 2 untersucht werden. Um solche Signaleinträge aus einem erweiterten Signalprotokoll zu ermitteln, soll die Java-Methode ermittleMoeglicheKontakte der Klasse Protokollpruefer implementiert werden. Dabei soll sie sowohl die Signalfrequenz als auch die Signalstärke überprüfen.

Der Methodenkopf der Methode lautet:

public List<Signal> ermittleMoeglicheKontakte(

List<Signal> pProtokoll)

d1)

d2)

public List<Signal> ermittleMoeglicheKontakte(List<Signal> pProtokoll) {

}

Du kannst auch nach Themen lernen

Übe ein Thema mit gemischten Aufgaben aus den Prüfungen aller Jahre.

Alle 10 Themen ansehen

Andere Prüfungen 2022

GK · Haupttermin (2022) · GK · Nachtermin (2022) · LK · Nachtermin (2022)