• Keine Ergebnisse gefunden

Dr. Johannes Mayer Abteilung Angewandte Informationsverarbeitung 10. Januar 2006

N/A
N/A
Protected

Academic year: 2021

Aktie "Dr. Johannes Mayer Abteilung Angewandte Informationsverarbeitung 10. Januar 2006"

Copied!
2
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Dr. Johannes Mayer Abteilung Angewandte Informationsverarbeitung 10. Januar 2006

Axel Blumenstock Blatt 10

Christian Ehrhardt

A

Allgemeine Informatik III / Systemnahe Software I (WS 2005/2006)

Abgabetermin: 17. Dezember 2005

Hash Mich (10 Punkte)

In Blatt 8 haben wir einen Worthäufigkeitszähler implementiert. Als Datenstruktur lag ein dynamischer Binärbaum zu Grunde, in dem jedes gelesene Wort nachgeschlagen werden konnte. Falls es gefunden wurde, wurde ein assoziierter Zähler inkrementiert, ansonsten ein neuer Eintrag mit dem Zählerstand 1 angelegt. Schließlich wurde der Baum durchlaufen und (Teile davon) als Worthäufigkeitstabelle ausgegeben.

Wurzel

Wort:

Häufigkeit: 1 ein

Wort:

Häufigkeit: 1 lichtlein Wort:

Häufigkeit: 1 brennt Wort:

Häufigkeit: 2 advent

Die in diesem Ablauf notwendigen Operationen setzen keineswegs voraus, dass die Daten- struktur ein Binärbaum ist. Wir können Vorbedingungen und Effekte dieser Operationen ohne Bezug auf die konkrete Implementierung beschreiben und zu einem abstrakten Da- tentyp namens Map (oder: Abbildung) zusammenfassen.

Zweck einer solchen Map ist, eine Menge von Schlüssel-Werte-Paaren so zu verwalten, dass jederzeit ein neuer Wert mit einem Schlüssel assoziiert werden sowie der zu einem Schlüssel gehörende Wert nachgeschlagen werden kann. Um unsere Implementierung nicht mehr auf eine Abbildung von Wörtern auf Häufigkeiten (Typ: char * -> int ) festzulegen, son- dern für Daten beliebigen Typs offen zu halten, verwenden wir für Schlüssel und Werte nunmehr untypisierte Zeiger (also void * ).

Im einzelnen soll unser Interface folgende Operationen umfassen:

• Map *mapCreate(Hasher, Comparator)

erzeugt eine neue Map. Die beiden übergebenen Funktionen 1 werden von der Map verwendet, um einen Schlüssel (der ja jetzt nicht mehr unbedingt ein String sein muss) auf einen Hashwert abzubilden, bzw. zwei Schlüssel zu vergleichen.

• void mapPut(Map *map, void *key, void *value)

assoziiert den gegebenen Wert value mit dem Schlüssel key. (Weder Wert noch Schlüssel werden dabei kopiert. Der Schlüssel darf danach nicht mehr verändert werden.) Ist bereits ein Eintrag mit demselben Schlüssel vorhanden, wird dieser überschrieben.

• void *mapGet(Map *map, void *key)

liefert den zuletzt mit key assoziierten Wert zurück, oder NULL, falls kein passender Eintrag gefunden wurde.

• int mapSize(Map *map)

gibt die Zahl der Einträge in der gegebenen Map zurück.

• void mapDump(Map *map, MapEntry **array)

legt Zeiger auf alle Einträge der Map in dem gegebenen array ab. Die Reihenfolge ist nicht spezifiziert. An dieser Stelle werden die Map-Einträge selbst ( struct s mit zwei untypisierten Zeigern) sichtbar.

• void mapFree(Map *map)

gibt den Speicher der gesamten Map-Struktur sowie sämtlicher Inhalte 2 frei.

• char *mapIdentify()

gibt lediglich einen String wie „tree map“ zur Identifikation der Implementierung zu- rück und sorgt für ein kleines schnelles Erfolgserlebnis.

Im Beispielverzeichnis zu diesem Blatt finden Sie zwei Dateien: die Headerdatei map.h , die im Wesentlichen obiges Map-Interface enthält, sowie wordfreq.c, welches dieses Interface anwendet, um analog zu Blatt 8 einen Worthäufigkeitszähler zu realisieren.

(a) (7 Punkte) Implementieren Sie in einer Datei treemap.c dieses Interface als unbalan- cierter Binärbaum, ganz analog zu Blatt 8. Die Hashfunktion benötigen Sie hier natür- lich nicht. Funktionen wie createEntry() , die nicht speziell mit Binärbäumen zu tun haben, sollten Sie in einer weiteren Quelltextdatei ( map.c ) ablegen.

(b) (3 Punkte) Schreiben Sie ein Makefile. Es soll insbesondere für das Target wf-tree den Worthäufigkeitszähler mit der Objektdatei treemap.o compilieren.

(c) (Zusatzaufgabe, 5 Punkte) Implementieren Sie dasselbe Interface aus map.h als Hash- tabelle in hashmap.c und erweitern Sie das Makefile entsprechend, so dass für das Target wf-hash die Objektdatei hashmap.o ohne treemap.o herangezogen wird.

Auf diese Weise umgehen wir Namenskonflikte.

1 Deklaration: typedef int (*Hasher)(void *) bzw. typedef int (*Comparator)(void *, void *)

2 In praktischen Anwendungen wäre die Freigabe der Inhalte möglicherweise nicht gewünscht.

(2)

Die genaue Umsetzung einer Hashtabelle sei Ihnen überlassen. Sie können sich aber an fol- genden Eckpunkten orientieren:

• Verwenden Sie ein Array mit N Einträgen. Da N mit dem unten gewählten s teiler- fremd sein soll, bietet sich an, hier eine Primzahl zu verwenden. Alternativ beispiels- weise eine Zweierpotenz, wenn unten s immer ungerade gewählt wird.

• Beim Eintragen oder Nachschlagen einer Assoziation bilden Sie aus dem Schlüssel den Hashwert, der modulo N einen Index i in das Array ergibt.

• Ist die entsprechende Zelle leer (beim Eintragen) bzw. werden (beim Nachschlagen) die Schlüssel von der Comparator-Funktion als identisch ausgewiesen, ist die Suche beendet.

• Ansonsten leiten wir aus dem Hashwert eine Schrittweite s ab und setzen unsere Suche an den Stellen ( i + k · s ) mod N mit k = 1, 2, . . . fort. Wenn N zu s teilerfremd ist und mindestens eine freie Zelle im Array existiert, muss diese Iteration nach spätestens N Schritten abbrechen. (Wir haben dann alle Zellen besucht).

• Ist das Array nach einem mapPut() zu mehr als 75 % gefüllt, verdoppeln wir seine Größe (in etwa; N muss ggf. wieder prim sein) und nehmen alle Einträge neu vor.

Viel Erfolg!

Referenzen

ÄHNLICHE DOKUMENTE

Unser find soll als Programmoptionen eine beliebige Zahl von Bedingungen (auch: Prä- dikaten), gefolgt von einer beliebigen Zahl von Verzeichnissen entgegennehmen und alle Dateien

derzeitiges Hoechstgebot (Frank Reich um 10:25:55): 3.12 Euro Gebot (in Cent) eingeben oder <ENTER> fuer Aktualisierung: 517 Gebot liegt nicht ueber aktuellem

Gesamtkosten = Fixkosten der Abteilung + Verdienst der Angestellten + Zus¨atzlich er- brachte Leistungen ( ¨ Uberstunden der Angestellten * halber Stundenlohn). • Abteilung

Ziel des Spiels 4-Gewinnt ist es, als erster von zwei Spielern vier Steine in einer Reihe, einer Spalte oder in einer Diagonalen zu bekommen. Dazu werfen die Spieler jeweils

M¨ochte ein Spieler gegen einen anderen Spieler antreten und es gibt bereits wartende Spieler, so werden diese angezeigt und der Spieler kann sich einen Gegenspieler aussuchen –

• Wird die Frage falsch beantwortet, ist das Spiel vorbei und der Kandidat erh¨alt 0, 500 oder 16000 Euro (je nachdem ob er gerade eine der ersten, der mittleren oder der

Implementieren Sie nun noch einen etwas sinnvolleren eigenen Layout-Manager names Table- Layout, bei dem man die Aufteilung des freien Platzes f¨ur die Spalten und Zeilen ¨uber

In der Methode generateHtml() wird dann ¨uber alle Komponenten iteriert um diese anschließend in tabellarischer Form auszugeben. Die Anzahl der Spalten kann ¨uber den