Was ich nicht verstehe ist, was diese Funktion tatsächlich tut?
Es Hashes im Grunde die Zeichenfolge durch den char *s
Zeiger zeigten, bis er das Ende der Saite auftritt, welche durch die '\0'
Nullzeichen gekennzeichnet ist. Mit anderen Worten, es berechnet (oder Karten) eine gegebene Eingabezeichenfolge zu einem ganzzahligen Wert.
Sie können auch sehen, dass es dies tut, indem sie in der Zeichenfolge (dh die s++
) durch jedes Zeichen gehen, so dass die Zeit Komplexität dieser Funktion linear abhängig von Stringlänge --oder O(N)
- und dass sie vermeidet Erzeugen eines Wertes, der über die Grenzen des Arrays mit der letzten Modulusoperation hinausgeht.
Ich denke, es generiert eine eindeutige Adresse (als Index für Hashtab) für die angegebene Zeichenfolge (char * s).
Es nimmt den Eingangswert (das heißt die Zeichenfolge gehasht wird) und verwendet es die Index im Array, um herauszufinden, in dem die Zeichenkette angeordnet werden sollen. Es erzeugt also technisch keine Adresse, weil die Funktion keinen Zeiger zurückgibt. Das Wort Offset wäre hier genauer.
Aber ich denke, zwei verschiedene Strings können den gleichen Index gegeben werden, da (Hashval% HASHSIZE) ist die angegebene Adresse (203% 101 = 405% 101 = 1).
Wahr. Dies wird als Kollision bezeichnet. Hash-Funktionen zu schreiben, die Kollisionen gut vermeiden, ist nicht einfach. In den meisten Diskussionen werden Methoden zur Kollisionsauflösung angezeigt, um diese Fälle zu behandeln. Eine Methode könnte beispielsweise sein, jedes Array-Element in einen Zeiger auf eine verknüpfte Liste umzuwandeln, in der die Elemente, die kollidiert sind (d. H. Den Hashed-Index-Wert haben), angehängt werden. Es gibt andere Methoden, aber das ist eine andere Diskussion.
Idealerweise würde perfect hash functions verwendet werden, weil sie zu garantiert werden nie den gleichen Hash-Wert für zwei verschiedene Eingänge erzeugen, so dass eine Kollisionsauflösung nicht erforderlich.
Es gibt Buchkapitel zu diesen Themen, vor allem, wenn es um die Suche geht. Vielleicht möchten Sie diese lesen.
Und warum HASHSIZE ist 101 und Hashval wird mit 31 multipliziert (warum nicht 100 oder 32)?
Wegen 101 und 31 sind prime Zahlen und daher weniger wahrscheinlich Kollisionen am Ende Erzeugung durch Multiplikation/sich in der gleichen Eimer wie eine vorhergehende und verschiedene, Kettenteilungs.