Hash-Tabellen VS assoziative Arrays

84

Kürzlich habe ich in einem sehr bekannten Buch " Introduction to Algorithms " über Hash-Tabellen gelesen . Ich habe sie noch nicht in echten Anwendungen verwendet, möchte es aber. Aber ich weiß nicht, wie ich anfangen soll. Kann mir jemand einige Beispiele für die Verwendung geben, zum Beispiel, wie man eine Wörterbuchanwendung (wie ABBYY Lingvo) mithilfe von Hash-Tabellen realisiert? Und schließlich möchte ich wissen, was der Unterschied zwischen Hash-Tabellen und assoziativen Arrays in PHP ist. Ich meine, welche Technologie soll ich in welchen Situationen verwenden? Wenn ich falsch liege (ich bitte um Verzeihung), korrigieren Sie mich bitte, da ich eigentlich mit Hash-Tabellen beginne und nur grundlegende (theoretische) Kenntnisse darüber habe. Vielen Dank.



Bakhtiyor
quelle

Antworten:

122

In PHP werden assoziative Arrays als Hashtabellen mit einigen zusätzlichen Funktionen implementiert.

Technisch gesehen ist ein assoziatives Array jedoch nicht identisch mit einer Hashtabelle - es wird einfach teilweise mit einer Hashtabelle hinter den Kulissen implementiert . Da der größte Teil seiner Implementierung eine Hashtabelle ist, kann sie alles tun, was eine Hashtabelle kann - aber sie kann auch mehr.

Sie können beispielsweise ein assoziatives Array mit einer for-Schleife durchlaufen, was mit einer Hashtabelle nicht möglich ist.

Während sie ähnlich sind, kann ein assoziatives Array tatsächlich eine Obermenge dessen ausführen, was eine Hashtabelle kann - sie sind also nicht genau dasselbe. Stellen Sie sich das als Hashtabellen und zusätzliche Funktionen vor.

Codebeispiele:

Verwenden eines assoziativen Arrays als Hashtabelle :

$favoriteColor = array();
$favoriteColor['bob']='blue';
$favoriteColor['Peter']='red';
$favoriteColor['Sally']='pink';
echo 'bob likes: '.$favoriteColor['bob']."\n";
echo 'Sally likes: '.$favoriteColor['Sally']."\n";
//output: bob likes blue
//        Sally likes pink

Durchlaufen eines assoziativen Arrays :

$idTable=array();
$idTable['Tyler']=1;
$idTable['Bill']=20;
$idTable['Marc']=4;
//up until here, we're using the array as a hashtable.

//now we loop through the array - you can't do this with a hashtable:
foreach($idTable as $person=>$id)
    echo 'id: '.$id.' | person: '.$person."\n";

//output: id: 1 | person: Tyler
//        id: 20 | person: Bill
//        id: 4 | person: Marc

Beachten Sie insbesondere, wie im zweiten Beispiel die Reihenfolge der einzelnen Elemente (Tyler, Bill Marc) basierend auf der Reihenfolge beibehalten wird, in der sie in das Array eingegeben wurden. Dies ist ein wesentlicher Unterschied zwischen assoziativen Arrays und Hashtabellen. Eine Hashtabelle behält keine Verbindung zwischen den darin enthaltenen Elementen bei, während dies bei einem assoziativen PHP-Array der Fall ist (Sie können sogar ein assoziatives PHP-Array sortieren).

Nocken
quelle
3
Hmmm, so eine kurze Erklärung. Also sind sie ABSOLUT dasselbe?
Bakhtiyor
2
@ Bak Sie sind nicht im Allgemeinen, aber sie sind in PHP, das ein bisschen schnell und locker mit Datenstrukturen spielt, da es weniger Bedenken hinsichtlich der Leistung gibt
Michael Mrozek
Ich verstehe, aber warum gibt es in diesem Fall so viele Algorithmen für Hash-Funktionen und ähnliches, wenn Hash-Funktion = Arrays?
Bakhtiyor
4
@ Michael du machst es wie ein Nachteil? Es macht PHP anders, aber ich denke, es ist ein guter Unterschied.
1
@Bakhityor: Dein letzter Satz ist perfekt. Sie müssen Hashtabellen jedoch nicht "vergessen" - in der Tat ist es großartig, dass Sie Hashtabellen bereits verstehen, da Sie dieses Wissen jetzt auf assoziative Arrays anwenden können. Ich füge meiner Antwort einige Beispiele hinzu, um die Sache für Sie weiter zu klären.
Cam
21

PHP-Arrays sind im Grunde Hash-Tabellen

Sergey Eremin
quelle
Edit: Ah - schlag mich drauf :) +1.
Cam
das ist was ich gesucht habe :)
Faizan
10
auf keinen Fall. Eine Hash-Tabelle würde eine Art Kollisionsauflösung erfordern, die PHP-Arrays nicht haben. Ihre Strategie zur Kollisionsauflösung ersetzt lediglich den alten Wert, und das ist per Definition keine Hash-Tabelle.
Juan
3
Soweit ich mich erinnere, bezieht sich die Kollisionsauflösung in Hash-Tabellen auf den Hash- Schlüssel und nicht auf den Originalschlüssel (Wie sollte das überhaupt funktionieren?)
Emanuel Oster
17

Der Unterschied zwischen einem assoziativen Array und einer Hash-Tabelle besteht darin, dass ein assoziatives Array ein Datentyp ist, während eine Hash-Tabelle eine Datenimplementierung ist. Offensichtlich ist der assoziative Array-Typ in vielen aktuellen Programmiersprachen sehr wichtig: Perl, Python, PHP usw. Eine Hash-Tabelle ist die Hauptmethode zum Implementieren eines assoziativen Arrays, aber nicht die einzige. Und assoziative Arrays sind die Hauptverwendung von Hash-Tabellen, aber nicht ganz die einzige Verwendung. Es ist also nicht so, dass sie gleich sind, aber wenn Sie bereits assoziative Arrays haben, sollten Sie sich normalerweise keine Gedanken über den Unterschied machen.

Aus Leistungsgründen kann es wichtig sein zu wissen, dass Ihre assoziativen Arrays in Ihrer Lieblingssprache als Hashes implementiert sind. Und es kann wichtig sein, eine Vorstellung von den Gemeinkosten dieser Implementierung zu haben. Hash-Tabellen sind langsamer und verbrauchen mehr Speicher als lineare Arrays, wie Sie in C sehen.

Perl fasst die beiden Konzepte zusammen, indem es assoziative Arrays "Hashes" nennt. Wie eine Reihe von Funktionen von Perl ist es nicht ganz falsch, aber es ist schlampig.

Greg Kuperberg
quelle
7

Ein Array in PHP ist eigentlich eine geordnete Karte, keine Hashtabelle. Der Hauptunterschied zwischen Karte und Hashtabelle besteht darin, dass die Reihenfolge, in der Elemente hinzugefügt wurden, nicht gespeichert werden kann. Andererseits sind Hashtabellen viel schneller als Karten. Die Komplexität beim Abrufen eines Elements aus der Karte ist O (nlogn) und aus der Hashtabelle ist O (1).

WoZ
quelle
4
"Die Komplexität beim Abrufen eines Elements aus der Karte ist O (nlogn)" - dies ist einfach nicht wahr. Selbst für eine LinkedList ist das Abrufen eines bestimmten Elements nur O (n). Wie unter en.wikipedia.org/wiki/Hash_table beschrieben , hat die in PHP zum Implementieren eines assoziativen Arrays verwendete Hash-Tabelle außerdem die Suche nach O (1)
StackG
1
Wie hier nach dem Überprüfen des Quellcodes erläutert , werden assoziative Arrays in PHP als Hash-Tabellen implementiert, wobei "jeder im Hash gespeicherte Wert mit dem zuvor gespeicherten Wert und dem danach gespeicherten Wert als verknüpfte Liste verknüpft ist". Dafür wird zusätzlicher Speicher benötigt, aber der Zugriff auf ein bestimmtes Element mit einem Schlüssel ist genauso schnell wie eine normale Hash-Tabelle, O (1), nicht langsamer.
Leopoldo Sanczyk
2

Ein assoziatives Array ist ein Array, in dem Sie nicht über einen Index, sondern über einen Schlüssel auf Elemente zugreifen. Wie dies intern funktioniert, ist implementierungsspezifisch (es gibt keine Regel, wie es funktionieren muss). Ein assoziatives Array könnte durch eine Hash-Tabelle implementiert werden (die meisten Implementierungen tun dies), aber es könnte auch durch eine Baumstruktur oder eine Sprungliste implementiert werden, oder der Algorithmus iteriert einfach über alle Elemente im Array und sucht nach einem Schlüssel das passt (das wäre furchtbar langsam, aber es funktioniert).

Eine Hash-Tabelle ist eine Möglichkeit, Daten zu speichern, bei denen Werte Schlüsseln zugeordnet sind und bei denen Sie Werte für Schlüssel innerhalb einer (normalerweise fast) konstanten Zeit suchen möchten. Dies klingt genau so, wie Sie es von einem assoziativen Array erwarten. Deshalb werden die meisten Hash-Tabellen für die Implementierung dieser Arrays verwendet, dies ist jedoch nicht obligatorisch.

Mecki
quelle