Esempio n. 1
0
        public string ToDotNotation(TrieOrder order)
        {
            var text = new StringBuilder();

            text.AppendLine("digraph g {");
            text.AppendLine("node[shape = circle];");

            var labels = new Dictionary <INode, int>();

            // Nodes
            labels.Add(root, 1);
            text.AppendLine($"node1[label=\"root\"]");

            foreach (var childLink in GetChildrenFromNode(root, order))
            {
                int childIndex = 0;
                if (!labels.TryGetValue(childLink.Node, out childIndex))
                {
                    childIndex = labels.Count + 1;
                    labels.Add(childLink.Node, childIndex);
                }
                text.AppendLine($"node1 -> node{childIndex} [label=\"&nbsp;{childLink.Label}\"]");
            }

            foreach (var link in Visit(order))
            {
                int index = 0;
                if (!labels.TryGetValue(link.Node, out index))
                {
                    index = labels.Count + 1;
                    labels.Add(link.Node, index);
                }

                if (link.Node.IsFinal)
                {
                    text.AppendLine($"node{index}[label=\"*\"]");
                }
                else
                {
                    text.AppendLine($"node{index}[label=\"\"]");
                }

                foreach (var childLink in GetChildrenFromNode(link.Node, order))
                {
                    int childIndex = 0;
                    if (!labels.TryGetValue(childLink.Node, out childIndex))
                    {
                        childIndex = labels.Count + 1;
                        labels.Add(childLink.Node, childIndex);
                    }
                    text.AppendLine($"node{index} -> node{childIndex} [label=\"&nbsp;{childLink.Label}\"]");
                }
            }

            text.AppendLine("}");
            return(text.ToString());
        }
Esempio n. 2
0
        private IEnumerable <ChildLink> GetChildrenFromNode(INode node, TrieOrder order)
        {
            var result = node.Children;

            if (order == TrieOrder.Asc)
            {
                result = result.OrderBy(c => c.Label, comparer);
            }
            else if (order == TrieOrder.Desc)
            {
                result = result.OrderByDescending(c => c.Label, comparer);
            }
            return(result);
        }
Esempio n. 3
0
        private IEnumerable <ChildLink> Visit(TrieOrder order)
        {
            var stack = new Stack <ChildLink>();

            foreach (var child in GetChildrenFromNode(root, order))
            {
                stack.Push(child);
            }

            while (stack.Count > 0)
            {
                var current = stack.Pop();
                foreach (var child in GetChildrenFromNode(current.Node, order))
                {
                    stack.Push(child);
                }

                yield return(current);
            }
        }
Esempio n. 4
0
        public IEnumerable <TrieMatch <T> > Match(ITrieMatcher <T> matcher, TrieOrder order)
        {
            var stack = new Stack <IEnumerator <ChildLink> >();

            stack.Push(GetChildrenFromNode(root, order).GetEnumerator());

            var result = new List <T>();

            try
            {
                while (stack.Count > 0)
                {
                    var current = stack.Peek();
                    if (!current.MoveNext())
                    {
                        if (result.Count > 0)
                        {
                            matcher.Pop();
                            result.RemoveAt(result.Count - 1);
                        }

                        current.Dispose();
                        stack.Pop();
                        continue;
                    }

                    var key   = current.Current.Label;
                    var match = matcher.Next(key);

                    if (match)
                    {
                        result.Add(key);

                        //TODO: Improve performance by checking only intersection of next characters from matcher and children

                        var matchNode = current.Current.Node;
                        stack.Push(GetChildrenFromNode(matchNode, order).GetEnumerator());

                        if (matchNode.IsFinal && matcher.IsFinal())
                        {
                            yield return(new TrieMatch <T>(result));
                        }
                    }
                }
            }
            finally
            {
                while (stack.Count > 0)
                {
                    var current = stack.Peek();
                    if (result.Count > 0)
                    {
                        matcher.Pop();
                        result.RemoveAt(result.Count - 1);
                    }

                    current.Dispose();
                    stack.Pop();
                }
            }
        }