예제 #1
0
        public Trie(IEnumerable <string> strings)
        {
            // O(m^2 * n)
            // n is a number of strings
            // m is a max length

            var root = new NodeString("");
            var eow  = new NodeString(".");

            foreach (var str in strings)
            {
                var node = root;

                foreach (var ch in str)
                {
                    var next = node.Children.FirstOrDefault(n => n.Value == ch.ToString());

                    if (next == null)
                    {
                        next = new NodeString(ch.ToString());
                        node.Children.Add(next);
                    }

                    node = next;
                }

                node.Children.Add(eow);
            }

            Root = root;
        }
예제 #2
0
 private static void Shrink(NodeString item)
 {
     while (item.Children.Count == 1)
     {
         var child = item.Children[0];
         item.Value   += child.Value;
         item.Children = child.Children;
     }
 }
예제 #3
0
        public void Insert(string s)
        {
            // O(m*n)

            // TODO: it is not working with non-empty root

            var inode = Root;
            var istr  = s + ".";

            while (true)
            {
                var isGoDeeper = false;

                foreach (var child in inode.Children)
                {
                    var common = istr.CommonPrefix(child.Value);

                    if (common.Length == child.Value.Length)
                    {
                        inode      = child;
                        istr       = istr.Substring(common.Length);
                        isGoDeeper = true;
                        break;                                                                          // Go deeper one level
                    }

                    if (common.Length > 0)
                    {
                        var remExisting = new NodeString(child.Value.Substring(common.Length))
                        {
                            Children = child.Children
                        };

                        var remInserting = new NodeString(istr.Substring(common.Length));

                        var commonNode = new NodeString(common);

                        inode.Children.Remove(child);

                        inode.Children.Add(commonNode);
                        commonNode.Children.Add(remExisting);
                        commonNode.Children.Add(remInserting);

                        return;                                                                         // Finish inserting
                    }
                }

                if (!isGoDeeper)
                {
                    // No child with appropriate prefix found

                    inode.Children.Add(new NodeString(istr));

                    return;
                }
            }
        }
예제 #4
0
        private static NodeString ConvertTrieToRadix(NodeString root)
        {
            // O(m*n)

            var queue = new Queue <NodeString>();

            queue.Enqueue(root);

            while (queue.Count > 0)
            {
                var item = queue.Dequeue();

                Shrink(item);

                foreach (var child in item.Children)
                {
                    queue.Enqueue(child);
                }
            }

            return(root);
        }
예제 #5
0
        public Radix(IEnumerable <string> strings)
        {
            var trie = new Trie(strings);

            Root = ConvertTrieToRadix(trie.Root);
        }