2009-03-13 6 views
5

Ich muss eine Nachschlagetabelle als Instanz Mitglied in einer meiner Klassen speichern. Die Tabelle wird beim Erstellen des Objekts initialisiert. Jede „Reihe“ haben drei „Säulen“:Was ist die beste Datenstruktur für diese In-Memory-Lookup-Tabelle?

StringKey (e.g., "car") 
EnumKey (e.g., LookupKeys.Car) 
Value (e.g, "Ths is a car.") 

ich die Datenstruktur auswählen möchten, die dafür Lookups entweder durch die StringKey oder der EnumKey die beste Leistung wird erhalten.

Es ist irgendwie peinlich mit 2 Tasten für den gleichen Wörterbuchwert. Ich habe das noch nie zuvor gesehen, also frage ich mich, was die Norm für diese Art von Ding ist.

Ich könnte eine Key/Value/Value-Struktur anstelle von Key/Key/Value, aber ich frage mich, welche Art von Auswirkungen auf die Leistung haben würde.

Denke ich über alles falsch?

Antwort

4

Sie haben zwei Hashmaps.

  • Eine von StringKey zu Wert.

  • Eins von EnumKey zu Wert.

  • Sie müssen nicht alle Value-Instanzen duplizieren, diese Objekte können zwischen den beiden Hashmaps geteilt werden.

    Wenn es eine Menge von Elementen ist, möchten Sie vielleicht zwei Treemaps anstelle von zwei hashmaps verwenden. Aber das wesentliche Prinzip ("Share the Values") gilt für beide Strukturen. Ein Satz von Werten mit zwei Karten.

    +0

    OK - also in meinem Beispiel sind die "Wert-Instanzen" nur Zeichenfolgen. Ich mache zwei Wörterbücher (eines mit StringKey, eines mit EnumKey), deren Werte die gleiche String-Referenzvariable enthalten. Klingt das richtig? –

    +0

    Genau. In Python ist das alles. In Java gibt es eine string.intern(), die sicherstellt, dass alle intern() 'd-Strings auf einen gemeinsamen String-Pool reduziert werden, wodurch einige mögliche Redundanzen eliminiert werden. –

    +0

    Ich verwende C# ... Wissen Sie, ob .NET eine Kopie der Zeichenfolge erstellt, wenn ich es jedem Wörterbuch hinzufüge? –

    5

    Nun ... "Falsch" ist eine harte Art, es zu sagen. Ich denke, da das gebräuchlichste Wörterbuch "single key to value" ist und viel Aufwand in die Bereitstellung effizienter Datenstrukturen dafür investiert (Maps), ist es oft am besten, nur zwei davon zu verwenden und den Speicher für die Werte zu teilen überhaupt möglich.

    1

    Ist es wirklich notwendig, in die gleiche Struktur mit beiden Arten von Schlüssel eingeben? Wahrscheinlich müssen Sie eine komplexe Datenstruktur nicht selbst erstellen. Sie könnten eine Art Kapselung für die Nachschlagetabelle durchführen, so dass Sie wirklich über zwei Nachschlagetabellen verfügen, wenn Speicher kein Problem darstellt. Sie könnten diese Verkapselungsstruktur verwenden, um zu simulieren, dass Sie den Wert aus der "gleichen" Struktur mit jedem Schlüsseltyp extrahieren können.

    ODER

    Wenn es ein Weg zwischen dem ENUM-Wert und dem String-Schlüssel kartieren Sie diesen Weg mit nur mit einer Art von Lookup-Tabelle gehen könnten.

    0

    LINQs ILookup (TKey, TElement) Schnittstelle kann helfen. Angenommen, Ihr Wörterbuch ist so etwas wie:

    Dictionary<carKey, carValue> cars; 
    

    Sie verwenden:

    ILookUp<carValue, carKey> lookup = cars.ToLookup(x => x.Value, x => x.Key); 
    

    (... eigentlich denke ich, ich könnte leicht die Frage falsch verstanden haben - aber ein ILookup vielleicht noch die Rechnung passen, aber Der Schlüssel/Wertsatz muss möglicherweise der Schlüssel und die Enumeration sein.)

    0

    Wenn jeder Wert garantiert für beide Schlüsseltypen verfügbar ist, wäre eine andere Idee, einen Schlüsseltyp in einen anderen zu konvertieren. Zum Beispiel:

    public Value getValue(String key) 
    { 
        dictionary.get(key); // normal way 
    } 
    
    public Value getValue(Enum enumKey) 
    { 
        String realKey = toKey(enumKey); 
        getValue(realKey); // use String key 
    } 
    

    könnten Sie haben Ihre Enum ein TOKEY() -Methode implementieren, die ihre String Schlüssel zurückgibt, oder vielleicht ein anderes Wörterbuch, die Enum-Werte zu den String Pendants abbildet.

    Verwandte Themen