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=\" {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=\" {childLink.Label}\"]"); } } text.AppendLine("}"); return(text.ToString()); }
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); }
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); } }
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(); } } }