Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.
Beide Seiten, vorherige Überarbeitung Vorherige Überarbeitung Nächste Überarbeitung | Vorherige Überarbeitung | ||
faecher:informatik:oberstufe:adt:set:implementationen:start [14.11.2021 18:07] – [Bitmasken] sbel | faecher:informatik:oberstufe:adt:set:implementationen:start [14.11.2021 18:42] (aktuell) – [Ist eine Zahl in der Menge enthalten?] sbel | ||
---|---|---|---|
Zeile 5: | Zeile 5: | ||
Die einfachste Lösung ist, wenn der ADT Set als interne Datenstruktur eine '' | Die einfachste Lösung ist, wenn der ADT Set als interne Datenstruktur eine '' | ||
Beim Einfügen muss immer getestet werden, ob der Wert bereits in der '' | Beim Einfügen muss immer getestet werden, ob der Wert bereits in der '' | ||
+ | |||
+ | ==== Bewertung ==== | ||
Zeile 35: | Zeile 37: | ||
</ | </ | ||
- | {{ : | + | {{ : |
Der binäre UND-Operator verknüpft zwei '' | Der binäre UND-Operator verknüpft zwei '' | ||
Zeile 50: | Zeile 52: | ||
| | ||
</ | </ | ||
- | {{ : | + | {{ : |
Der binäre ODER-Operator verknüpft zwei '' | Der binäre ODER-Operator verknüpft zwei '' | ||
Zeile 74: | Zeile 76: | ||
</ | </ | ||
- | {{ : | + | {{ : |
+ | |||
+ | ==== Zahlbereichserweiterung ==== | ||
+ | |||
+ | Mit einer einzelnen 32-Bit-Zahl kann man Mengen der Zahlen 0 bis 31 abbilden. Will man größere Werte erlauben, benötigt man eine ArrayList von Integer-Zahlen. | ||
+ | |||
+ | Die k-te Zahl der ArrayList repräsentiert damit die Elemente mit den Werten 32·k bis 32·k+31. | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | Das Element '' | ||
+ | |||
+ | Beim Einfügen muss die ArrayList ggf. um Elemente erweitert werden, so dass sie groß genug ist. | ||
+ | |||
+ | Pseudocode: | ||
+ | |||
+ | < | ||
+ | einfuegen(n: | ||
+ | k = n / 32 | ||
+ | solange Länge von daten ≤ k: | ||
+ | hänge 0 an daten an | ||
+ | bit = n % 32 | ||
+ | maske = 1 << bit | ||
+ | daten[bit] = daten[bit] | maske | ||
+ | </ | ||
+ | |||
+ | ==== Bewertung ==== | ||
+ | |||
+ | |||
+ | === Vorteile: === | ||
+ | |||
+ | * Sehr speichereffizient, | ||
+ | * Lesender Zugriff in konstanter Anzahl von Schritten möglich | ||
+ | * Schreibender Zugriff meistens schnell möglich | ||
+ | |||
+ | === Nachteile: === | ||
+ | |||
+ | * Wenn nur wenige, aber große Werte gespeichert werden, wird Speicher verschwendet | ||
+ | * Konzept ist nur zum Speichern von Integer-Zahlen anwendbar | ||
+ | |||
+ | |||
+ | ===== Variante 3: Hashtable ===== | ||
+ | |||
+ | Die Hashtable verwendet ein Array, das die Werte der Menge enthält. | ||
+ | |||
+ | Das Problem ist, dass die Suche nach einem Wert unter Umständen sehr lange dauert – insbesondere, | ||
+ | |||
+ | Die Idee des Hashings ist, dass man einem Wert " | ||
+ | Wir nehmen als erstes Beispiel ein Array mit 10 Plätzen: | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | Um den Speicherort eines Wertes '' | ||
+ | '' | ||
+ | < | ||
+ | einfuegen(42) → Position 42 mod 10 = 2, daten[2] = 42 | ||
+ | einfuegen(77) → Position 77 mod 10 = 7, daten[7] = 77 | ||
+ | </ | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | Um herauszufinden, | ||
+ | |||
+ | < | ||
+ | enthaelt(42) → Position 42 mod 10 = 2, daten[2] == 42 → ja | ||
+ | enthaelt(23) → Position 23 mod 10 = 3, daten[3] ist leer → nein | ||
+ | enthaelt(17) → Position 17 mod 10 = 7, daten[7] != 17 → nein | ||
+ | </ | ||
+ | |||
+ | Dieses Vorgehen ist sehr schnell, da die Operationen nicht von der Anzahl der Werte in der Menge abhängig sind. | ||
+ | |||
+ | <WRAP center round box 90%> | ||
+ | Die Funktion '' | ||
+ | |||
+ | Hashfunktionen bilden eine große Menge von Eingabewerten (hier: alle int-Zahlen) auf einen kleinen Bereich von Ausgabewerten ab (hier: die Zahlen von 0 bis 9). | ||
+ | |||
+ | Für unsere Datenstruktur ist die Hashfunktion | ||
+ | |||
+ | '' | ||
+ | </ | ||
+ | |||
+ | ==== Kollisionen ==== | ||
+ | |||
+ | "Aber was macht man, wenn zwei Zahlen den gleichen Hashwert erhalten?" | ||
+ | |||
+ | Wenn zwei unterschiedliche Zahlen den gleichen Hashwert bekommen, spricht man von einer **Kollision**. Kollisionen sind bei Hashfunktionen unvermeidlich, | ||
+ | |||
+ | Im Beispiel würde die Zahl '' | ||
+ | |||
+ | Eine Möglichkeit ist, dass man an einer Stelle im Array nicht nur eine einzelne Zahl speichert, sondern mehrere (einen " | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | Wenn man bestimmen will, ob ein Wert '' | ||
+ | |||
+ | * Bestimme den Index von x (z.B. '' | ||
+ | * Untersuche alle Werte in diesem Behälter. Wenn einer davon gleich '' | ||
+ | |||
+ | Ein Behälter kann z.B. mit einer '' | ||
+ | |||
+ | Der Speicheraufwand ist etwas höher und auch das Durchsuchen der Behälter dauert etwas länger. | ||
+ | |||
+ | "Aber was haben wir damit jetzt gewonnen? Wir müssen immer noch die Behälter komplett durchsuchen!" | ||
+ | |||
+ | Das stimmt, allerdings ist es sehr unwahrscheinlich, | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | Zudem kann man mit **Rehashing** die Elemente neu verteilen, wenn die Auslastung einen bestimmten Grenzwert (z.B. 75%) überschreitet. | ||
+ | |||
+ | Die Auslastung bezeichnet das Verhältnis der gespeicherten Werte zur Länge des Arrays. \\ Im Beispiel: 8 Elemente, 10 Plätze → Auslastung = 80% | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | Man legt ein neues Array der Länge z.B. 21 an und sortiert die bestehenden Werte neu ein. Viele der Kollisionen treten jetzt nicht mehr auf, es können aber neue Kollisionen entstehen, die Behälter enthalten jetzt im Durchschnitt weniger als einen Wert. | ||
+ | |||
+ | Die Rehashing-Operation ist sehr zeitaufwendig, | ||
+ | Im Durchschnitt ist der lesende und schreibende Zugriff auf die Werte in konstanter Zeit möglich, also unabhängig von der Anzahl der Elemente im Set. | ||
+ | |||
+ | Wenn man im Vorfeld bereits weiß, wie viele Elemente vermutlich gespeichert werden sollen, kann man bereits beim Erzeugen das Array entsprechend anlegen. | ||
+ | |||
+ | ==== Bewertung ==== | ||
+ | |||
+ | |||
+ | === Vorteile: === | ||
+ | |||
+ | * Im Durchschnitt sehr schnell | ||
+ | * Auf beliebige Datentypen anwendbar (in Java: Methode '' | ||
+ | |||
+ | === Nachteile: === | ||
+ | * Hoher Speicherbedarf | ||
+ | * Kann in seltenen (konstruierten) Fällen langsam arbeiten |