Ich suche nach einer Datenstruktur ähnlich einem Wörterbuch, das die Menge aller verwandten Elemente an einen Schlüssel zurückgibt.
Zum Beispiel würde ich es so verwenden:
%Vor%In diesem Fall wäre alternateNames1 ein Array mit "Liz" und "Elizabeth" und alternateNames2 wäre ein Array mit "Elizabeth" und "Betty".
Ich möchte das nicht neu erfinden, aber ich konnte keine Beispiele für eine solche Struktur finden.
Aktualisieren
Danke an diejenigen, die mit Vorschlägen zurück geschrieben haben. Viele Leute haben vorgeschlagen, eine Version von Dictionary<string, IEnumerable<string>>
zu verwenden. Momentan verwende ich diesen Ansatz, aber er erfüllt die Anforderung nicht wirklich, ohne schrecklich schwierig zu warten. Jeder Wert in jeder Liste muss in der Lage sein, als Schlüssel für jeden anderen Wert zu dienen, der ihm in einem Satz hinzugefügt wurde.
Also, angesichts der folgenden:
%Vor%Ich würde erwarten, dass Stellvertreter jetzt "Elizabeth" und "Liz" enthalten.
Es sieht so aus, als müsste ich einfach eine solche Struktur aufbauen, die meinen Bedürfnissen entspricht. Halten Sie die Ideen bereit!
Brian
Ihr Problem hört sich an, als wäre es wirklich ein Grafikproblem . Stellen Sie sich die Namen als Knoten und die Mitgliedschaft in der Menge als Kanten vor. Von diesem Standpunkt aus möchten Sie eine Datenstruktur, die sparse Graphen gut behandelt, wie eine Adjazenzliste . Dies ist natürlich ähnlich zu dem, was Sie bereits mit Dictionary<string, IEnumerable<string>>
tun, aber wenn Sie so darüber nachdenken, könnten Sie zu einigen hilfreichen Implementierungen und Algorithmen gelangen.
System.Collections.Generic Namespace und die System.Collections werden mit KeyValue-Paar-Wörterbüchern, sortierten Wörterbüchern, Listenobjekten und vielem mehr geladen.
%Vor%oder eine verschachtelte Liste in einem Wörterbuch
%Vor%Nur ein Gedanke in eine andere Richtung - stark typisierte Datensätze scheinen eine Menge für sie zu haben. Und als Byte-Arrays serialisiert sind sie ziemlich schnell, um multidimensional strukturierte Daten zu verschieben.
Iteration und Linq-Fähigkeit sind eine Art eingebaut.
Vielleicht für viele Sachen übertrieben, aber ich habe eine Reihe von Stellen, an denen ich den ganzen Datensatz in einer varbinary (max) Spalte in SQL gespeichert habe.
Sie haben grundsätzlich ein Wörterbuch, in dem mehrere Schlüssel auf denselben Wert abgebildet werden. Es gibt keine integrierte Datenstruktur, die die gewünschte Operation unterstützt, aber sie kann einfach in%: Dictionary{string, HashSet{string}}
in .NET dargestellt werden:
Sie können sich Ihre Datenstruktur als gerichteter Graph vorstellen, bei dem jeder Knoten eine Kante hat, die mit dem zugehörigen Namen verbunden ist. Da es n ^ 2 Kanten gibt, benötigt das Wörterbuch O (n ^ 2) Zeit zum Einfügen und Speichern. Es ist nicht möglich, die Nachschlagezeit auf etwas Besseres zu reduzieren.
Glücklicherweise, da es als ein Wörterbuch implementiert ist, suchen Sie immer noch nach O (1). Löschungen sind O (m), wobei m die Anzahl der Werte ist, die sich auf einen Schlüssel beziehen.
Der de-facto-alt.net-Standard ist in Iesi.Collections, aber die Basisklassenbibliothek hat nur HashSet<T>
in dotnet 3.5 oder höher.
Ich habe "group by" likes in linq verwendet, um Duplikate aus beliebigen IEnumerable<T>
collections einfach zu entfernen, aber das gibt Ihnen keine Set-Semantik.
HashSet & lt; & gt; ist nahe, was Sie wollen.
Basierend auf Ihren Anforderungen, glaube ich nicht, dass es etwas von der Stange gibt, das Strings zu bereits existierenden Sammlungen abbildet; Im Grunde müssten Sie eine Klasse schreiben, die eine Methode wie StoreAssociations<<T>>(IEnumerable<<T>> names)
verwendet, IEnumerable in HashSet konvertiert und jedes Element im HashSet iteriert, um eine Zuordnung in einem IDictionary<string,HashSet<T>>
zum neu erstellten Hashset hinzuzufügen.
Wie wäre es mit einem Paar Datenstrukturen: Dictionary<string, Guid>
und Dictionary<Guid, List<string>>
Um ein Schlüsselpaar hinzuzufügen (a, b) [Sie können eine größere Summe in Paare zerlegen (1 + 2, 2 + 3, ...) wie folgt vorgehen: -
Suchen Sie a und b im ersten Wörterbuch.
Wenn keine existiert, erstellen Sie eine neue GUID und fügen Sie (a, g) und (b, g) zum ersten Wörterbuch und (g, Liste {a}) und (g, Liste {b}) zum zweiten Wörterbuch hinzu.
Wenn einer existiert, sagen Sie a, nehmen Sie die GUID daraus (g) und fügen Sie den anderen (b, g) dem ersten Wörterbuch hinzu und heften Sie b an das Ende der Liste, die sich im zweiten Wörterbuch befindet.
Wenn beide existieren UND sie die gleiche Guid haben - nichts zu tun.
Wenn beide existieren und sie verschiedene Guids haben, müssen Sie die beiden Sets zusammenführen // Das ist etwas, was die meisten der anderen vorgeschlagenen Lösungen zu vermissen scheinen // Wähle also ein Guid aus, um es zu eliminieren, hol es aus dem zweiten Dictionary, Fügen Sie dem anderen Eintrag die Liste der Zeichenfolgen hinzu, und entfernen Sie diesen Eintrag. Markieren Sie abschließend alle Wörter im ersten Wörterbuch, die in dieser Liste waren.
Um alle verwandten Wörter zu erhalten, suchen Sie die Guid im ersten Wörterbuch und greifen Sie die Liste aus dem zweiten Wörterbuch.
Natürlich würde ein statisch inkrementierender Long-Wert wahrscheinlich besser funktionieren als ein Guid.
Oder, da List ein Referenztyp ist, könnten Sie Folgendes tun ...
%Vor%Gehen Sie wie folgt vor: -
Um eine einzelne Assoziation (a = b) {von einer Liste von Äquivalenten zerlegt} hinzuzufügen
Suchen Sie a und b im Dictionary
Wenn keine existiert
%Vor%Wenn einer existiert, sagen wir,
%Vor%Wenn beide existieren und die Listen gleich sind (Objektvergleich), sind Sie fertig.
Wenn beide existieren und die Listen unterschiedlich sind:
%Vor%Ich habe etwas Code geschrieben, ich weiß nicht, wie effizient es ist, aber ich denke, dass es das tut, was Sie wollen.
Es ist deine Struktur
%Vor%und du kannst es benutzen, so
%Vor%Ich benutze das:
Es hat ein generisches Set & lt; a & gt; Geben und implementieren Sie alle schönen Iteratoren, .Contains, .Count, etc.
Tags und Links .net data-structures set