Skip to content
Snippets Groups Projects
Commit 9a7abc22 authored by Peter Gerwinski's avatar Peter Gerwinski
Browse files

Beispiele und Notizen 28.4.2022: Hash-Tabelle

parent 481b5377
No related branches found
No related tags found
No related merge requests found
Wie lösen wir das Problem der Speicherineffizienz?
- "zu große" Hash-Funktion wählen, danach modulo einer "krummen" Zahl rechnen,
typischerweise eine Primzahl
- Programm "gperf":
Die Wörter sind vorher bekannt. (Sonst nicht einsetzbar.)
Das Programm erzeugt eine "perfekte" Hash-Tabelle (d.h. ohne Kollisionen).
Einsatz in gcc und verwandten Compilern zur Erkennung von Schlüsselwörtern
- Ansonsten: Kollisionsbehandlung
- z.B.: wenn Stelle bereits besetzt, weiterwnadern, freie Stelle finden
(z.B.: "sieben" bei 't' statt bei 's' speichern)
- oder: an jeder Stelle eine verkettete Liste von Möglichkeiten (dort: O(n))
- oder: an jeder Stelle eine weitere Hash-Tabelle
siehe: https://de.wikipedia.org/wiki/Hashtabelle
#include <stdio.h>
#include <string.h>
#include <stdint.h>
int n[65536]; /* zunächst: alle 0 */
const char *check[65536]; /* zunächst: alle NULL */
uint16_t hash (const char *name)
{
if (name && name[0])
{
uint8_t first_char = name[0];
uint8_t second_char = name[1];
return first_char + 256 * second_char;
}
else
return 0;
}
void put_number (const char *name, int value)
{
/* Nimm die ersten 2 Zeichen des Strings,
* berechne daraus einen Array-Index von 0 bis 65535.
* Dort hinterlege die Zahl "value" im Array.
*/
int i = hash (name);
n[i] = value;
check[i] = name; /* Funktioniert so bei String-Konstanten. Ansonsten: String kopieren. */
}
int get_number (const char *name) /* nicht mehr geschummelt, O(1), aber: */
{ /* - Speicher-ineffizient */
int value = -1;
/* Nimm die ersten 2 Zeichen des Strings,
* berechne daraus einen Array-Index von 0 bis 65535.
* Dort entnimm die Zahl "value".
*/
int i = hash (name);
if (!strcmp (name, check[i]))
value = n[i];
return value;
}
void debug_hash_table ()
{
for (int i = 0; i < 65536; i++)
if (n[i])
printf ("%04x %2d %s\n", i, n[i], check[i]);
}
int main (void)
{
put_number ("eins", 1);
put_number ("zwei", 2);
put_number ("drei", 3);
put_number ("vier", 4);
put_number ("fünf", 5);
put_number ("sechs", 6);
put_number ("sieben", 7);
put_number ("acht", 8);
put_number ("neun", 9);
put_number ("zehn", 10);
debug_hash_table ();
int eins = get_number ("eins");
int zwei = get_number ("zwei");
int drei = get_number ("drei");
int vier = get_number ("vier");
int fuenf = get_number ("fünf");
int sechs = get_number ("sechs");
int sieben = get_number ("sieben");
printf ("%d %d %d %d %d %d %d\n", eins, zwei, drei, vier, fuenf, sechs, sieben);
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment