Eins-zu-eins-Mapping-Datenstruktur (A, B) mit getKey (B) in O (1)?

7

Diese Frage wurde anfänglich falsch formuliert, siehe EDIT unten. Ich werde es für den Kontext überlassen.

Ich habe über intelligente Wege nachgedacht, um ein bijektives (d. h. Eins-zu-eins) Mapping zu erstellen. Das Zuordnen einer Funktion A- & gt; B (Viele-zu-Eins) ist im Grunde was HashMap (A, B) tut. Wenn ich jetzt eine Datenstruktur haben möchte, die etwas eins zu eins mit contains () in O (1) implementiert, würde es etwas in den Java-Standardbibliotheken geben, das ich verwenden könnte? Wohlgemerkt, ich brauche das jetzt für nichts, das war etwas, über das ich kürzlich nachgedacht habe und für das ich keine Datenstruktur finden konnte, also sind die Antworten keine Eile. Gibt es eine solche Klasse? Wenn nicht, was denkst du warum das ist?

Alles, was ich über SO finden konnte, waren Dinge über den Winterschlaf, die mir nicht weiterhelfen konnten.

BEARBEITEN: Meine Frage wurde schlecht formuliert, daher ist eine Erklärung fällig.

Was ich meinte, ist die "rückwärtige" Abbildung B- & gt; A. HashMap (A, B) enthält (A) und enthält (B) beide in O (1), das ist nicht das, was ich meinte, Entschuldigung für die Verwirrung. Was ich meinte war, gibt es eine Datenstruktur Mapping A & lt; - & gt; B, die getValue (A) und getKey (B) in O (1) hat?

Ich weiß, dass dies mit zwei HashMaps (A, B) und (B, A) geschehen könnte, die dieselbe Beziehung enthalten, aber ich denke, dass es eine Datenstruktur geben sollte, die das erledigt, ohne es tun zu müssen. manuell ".

    
G. Bach 22.06.2012, 19:25
quelle

5 Antworten

6

Ich kenne keine existierende Klasse, die O (1) sowohl für containsKey als auch für containsValue tut, aber Sie können HashMap erweitern, so dass Sie beim Einfügen jeden Wert zu einem internen HashSet hinzufügen. Überladen von containsValue, um eine Suche nach den Werten von HashSet durchzuführen. Die Standard-HashMap hat O (1) containsKey, aber O (n) enthältValue.

Ebenso können Sie in der Einfügung 1: 1 erzwingen und nach vorhandenen Werten suchen.

Beachten Sie, dass die HashSet-Suche im schlimmsten Fall zu O (n) führen kann, wenn Sie eine Menge Kollisionen erhalten.

    
Thomas 22.06.2012, 19:42
quelle
11

Ich glaube nicht, dass du es besser machst als zwei HashMaps. Das Schreiben der Wrapper-Oberfläche ist sehr einfach:

%Vor%

Ich bin mir nicht sicher, ob dies ein gültiges Java ist, aber Sie haben die Idee.

    
japreiss 22.06.2012 19:49
quelle
4

Wenn Sie bereit sind, Bibliotheken von Drittanbietern zu verwenden, bietet Guava dafür eine nette API als BiMap . Anstelle einer getKey -Methode wird eine inverse() -Ansicht bereitgestellt, die ein BiMap<V, K> zurückgibt. (Es liefert natürlich die Konstante containsValue .)

Momentan ist HashBiMap im Grunde intern zwei HashMap s synchronisiert - obwohl es sehr konsistent ist, wie sie sich gegenseitig anpassen - aber die Implementierung könnte in Zukunft intelligenter werden.

>     
Louis Wasserman 22.06.2012 20:59
quelle
3

Ich hatte die gleiche Notwendigkeit und kam mit dieser BiMap, die nützlich sein könnte. Es verwendet nur eine Hashmap und gibt ein Eintragsobjekt zurück, so dass der Rückgabewert einen bestimmten Typ erhalten kann und auch ein Mapping auf null möglich ist.

%Vor%     
user2219808 26.07.2015 11:34
quelle
2

Mein erster Gedanke ist, nur eine Standardkarte zu verwenden. Wenn Sie eine perfekte Hash-Funktion haben, können Sie eine HashMap als Eins-zu-Eins-Zuordnung verwenden. Wenn ich verstehe, was Sie tun, würde das Folgende ausreichen:

%Vor%     
Woot4Moo 22.06.2012 19:32
quelle

Tags und Links