Ich bekomme das Konzept hinter einem trie. Aber ich bin ein wenig verwirrt, wenn es um die Umsetzung geht.Was wäre ein sinnvoller Weg, ein Trie in .NET zu implementieren?
Der offensichtlichste Weg, den ich denken könnte, um eine Trie
Art zu strukturieren, wäre eine Trie
pflegen eine interne Dictionary<char, Trie>
zu haben. Ich habe tatsächlich eine auf diese Weise geschrieben, und es funktioniert, aber ... das scheint wie Overkill. Mein Eindruck ist, dass ein Trie leicht sein sollte, und eine separate Dictionary<char, Trie>
für jeden Knoten scheint mir nicht sehr leicht.
Gibt es eine geeignetere Methode, um diese Struktur zu implementieren, die ich vermisse?
UPDATE: OK! Basierend auf die sehr hilfreich Eingabe von Jon und leppie, ist das, was ich mit so weit habe kommen:
(1) Ich habe den Trie
Typen, der Trie.INodeCollection
ein eigenes _nodes
Mitglied des Typs hat.
(2) Die Trie.INodeCollection
Schnittstelle hat die folgenden Mitglieder:
interface INodeCollection
{
bool TryGetNode(char key, out Trie node);
INodeCollection Add(char key, Trie node);
IEnumerable<Trie> GetNodes();
}
(3) Es gibt drei Implementierungen dieser Schnittstelle:
class SingleNode : INodeCollection
{
internal readonly char _key;
internal readonly Trie _trie;
public SingleNode(char key, Trie trie)
{ /*...*/ }
// Add returns a SmallNodeCollection.
}
class SmallNodeCollection : INodeCollection
{
const int MaximumSize = 8; // ?
internal readonly List<KeyValuePair<char, Trie>> _nodes;
public SmallNodeCollection(SingleNode node, char key, Trie trie)
{ /*...*/ }
// Add adds to the list and returns the current instance until MaximumSize,
// after which point it returns a LargeNodeCollection.
}
class LargeNodeCollection : INodeCollection
{
private readonly Dictionary<char, Trie> _nodes;
public LargeNodeCollection(SmallNodeCollection nodes, char key, Trie trie)
{ /*...*/ }
// Add adds to the dictionary and returns the current instance.
}
(4) Wenn ein Trie
zuerst aufgebaut wird, sein _nodes
Mitglied ist null
. Der erste Aufruf an Add
erstellt eine SingleNode
, und nachfolgende Aufrufe an Add
gehen von dort, entsprechend den oben beschriebenen Schritten.
Macht das Sinn? Dies fühlt sich an wie eine Verbesserung in dem Sinne, dass es etwas reduziert die "Sperrigkeit" von Trie
(Knoten sind nicht mehr voll Dictionary<char, Trie>
Objekte, bis sie eine ausreichende Anzahl von Kindern haben). Es ist jedoch auch wesentlich komplexer geworden. Ist es zu kompliziert? Habe ich einen komplizierten Weg eingeschlagen, um etwas zu erreichen, das einfach hätte sein sollen?
Sie könnten auch den Schwanz komprimieren, wie im Fall des einzelnen Unterknotens. – leppie