static bool SubTreeMatch(ICommonTreeNode superNode, ICommonTreeNode subNode) { if (superNode.Value != subNode.Value) { return(false); } var superChildEnumerator = superNode.Children.GetEnumerator(); bool hasNext = superChildEnumerator.MoveNext(); /* for every child subtree of subNode (in order), see if that subtree is found in one of the supernodes child subtrees (in order) */ foreach (var subChild in subNode.Children) { bool found = false; while (!found) { if (!hasNext) { return(false); } if (SubTreeMatch(superChildEnumerator.Current, subChild)) { found = true; } hasNext = superChildEnumerator.MoveNext(); } } return(true); }
private Int32 VisitChild(ICommonTreeNode node) { Int32 nodeIndex = ++lastIndex; textTree.vLabel[nodeIndex] = (Int32)TextTree.LabelMapping[node.Value]; Int32 lastChildIndex = -1; foreach (var child in node.Children) { Int32 childIndex = VisitChild(child); // set the parent of the child node to this node textTree.parent[childIndex] = nodeIndex; // set the first child of this node to the first node in the list of children if (lastChildIndex == -1) { textTree.firstChild[nodeIndex] = childIndex; } else // connect siblings to each other (if this is not the first child) { textTree.nextSibling[lastChildIndex] = childIndex; } lastChildIndex = childIndex; } return(nodeIndex); }
public static bool TreesAreExactMatch(ICommonTreeNode tree1, ICommonTreeNode tree2) { if (tree1.Value != tree2.Value) { return(false); } var child1Enumerator = tree1.Children.GetEnumerator(); var child2Enumerator = tree2.Children.GetEnumerator(); while (true) { bool hasNext1 = child1Enumerator.MoveNext(); bool hasNext2 = child2Enumerator.MoveNext(); if (hasNext1 != hasNext2) { return(false); } if (hasNext2 == false) { return(true); } if (!TreesAreExactMatch(child1Enumerator.Current, child2Enumerator.Current)) { return(false); } } }
//TODO this implementation is probably horribly inefficient. Could just pass a list along //or better yet use my own stack to handle the traversal public static IEnumerable <ICommonTreeNode> PreOrderNodeTraversal(ICommonTreeNode node) { yield return(node); foreach (var child in node.Children) { foreach (var childNode in PreOrderNodeTraversal(child)) { yield return(childNode); } } }
public TextTree ConvertToCMOrderedTreeMinerTree(ICommonTree tree) { ICommonTreeNode root = tree.Root; Int32 size = (Int32)TreeUtil.SizeOfTree(root); textTree = new TextTree(tree.SourceTag, size); lastIndex = -1; VisitChild(root); return(textTree); }
public static string StringRepresentation(this ICommonTreeNode node) { if (node == null) { throw new ArgumentNullException(nameof(node)); } var sb = new StringBuilder(); StringRepresentationRec(sb, node); sb.Length -= 1; return(sb.ToString()); }
private static void StringRepresentationRec(StringBuilder sb, ICommonTreeNode node, string indent = "") { sb.Append("{ \"type\": \""); sb.Append(node.Value); sb.Append("\", \"children\": ["); node.Children.ForEach(c => StringRepresentationRec(sb, c, indent)); if (node.Children.Count() > 0) { sb.Length -= 1; } sb.Append("] },"); }
public static bool IsEqual(ICommonTreeNode node1, ICommonTreeNode node2) { // if the values in the nodes differ, they're different if (node1.Value != node2.Value) { return(false); } // if neither has a child, then they're equal if (node1.Children == null && node2.Children == null) { return(true); } // if one has children and the other does not, they're different if (node1.Children == null || node2.Children == null) { return(false); } var enum1 = node1.Children.GetEnumerator(); var enum2 = node2.Children.GetEnumerator(); bool hasNext1; bool hasNext2; while (true) { hasNext1 = enum1.MoveNext(); hasNext2 = enum2.MoveNext(); //if one has a next child and the other doesn't, then they are different if (hasNext1 != hasNext2) { return(false); } // if they both are out of chilren, then they are the same if (hasNext1 == false) { return(true); } // if any of their children differ, then they are different if (!IsEqual(enum1.Current, enum2.Current)) { return(false); } } }
public static JsonNode ConvertToJsonNode(ICommonTreeNode node) { string name = null; JsonNodeKind kind; if (!Enum.TryParse(node.Value, out kind)) { kind = JsonNodeKind.Identifier; name = node.Value; } JsonNode jNode = new JsonNode(kind, "unknown", name); node.Children.ForEach(c => jNode.AddChild(ConvertToJsonNode(c))); return(jNode); }
public static bool IsTreeSubtreeOfTree(ICommonTreeNode subtree, ICommonTreeNode superTree) { // find all nodes in the supertree that match the root of the subtree if (subtree.Value == superTree.Value) { if (IsTreeSubtreeOfTreeRec(subtree, superTree)) { return(true); } } foreach (var child in superTree.Children) { if (IsTreeSubtreeOfTree(subtree, child)) { return(true); } } return(false); }
private static bool IsTreeSubtreeOfTreeRec(ICommonTreeNode subtree, ICommonTreeNode supertree) { // this is wrong because it bails if the roots aren't the same // but the root of the subtree may be somewhere deep in the subtree if (subtree.Value != supertree.Value) { return(false); } var enumerator = supertree.Children.GetEnumerator(); bool hasNext = enumerator.MoveNext(); // if the values of the nodes match and the subtree has no children, then it's a match if (subtree.Children == null) { return(true); } foreach (var child in subtree.Children) { // if we run out of children in the supertree, then subtree is not a subtree while (true) { // if we ever run out of nodes in the supertree, then subtree is not a true subtree if (!hasNext) { return(false); } // if it's a match, then great! break out and move to the next child if (IsTreeSubtreeOfTreeRec(child, enumerator.Current)) { break; } hasNext = enumerator.MoveNext(); } } // we found a match for every child in subtree, so it must be a match return(true); }
/* look for match of the root of the subtree against all nodes in the superTree */ static List <ICommonTreeNode> MatchRoots(ICommonTreeNode superTree, ICommonTreeNode subRoot) { var stack = new Stack <ICommonTreeNode>(); stack.Push(superTree); var matchingNodes = new List <ICommonTreeNode>(); while (stack.Count > 0) { var potentialMatchNode = stack.Pop(); if (SubTreeMatch(potentialMatchNode, subRoot)) { matchingNodes.Add(potentialMatchNode); } foreach (var child in potentialMatchNode.Children) { stack.Push(child); } } return(matchingNodes); }
public static int NumberOfNodesStartingWithSubstring(ICommonTreeNode node, string substring) { return((node.Value.StartsWith(substring) ? 1 : 0) + node.Children.Sum(child => NumberOfNodesStartingWithSubstring(child, substring))); }
public static int NumberOfNodesContainingSubstring(ICommonTreeNode node, string substring) { return((node.Value.Contains(substring) ? 1 : 0) + node.Children.Sum(child => NumberOfNodesContainingSubstring(child, substring))); }
public static int SizeOfTree(ICommonTreeNode node) { return(1 + node.Children.Select(c => SizeOfTree(c)).Sum()); }
public static bool TreeContainsOtherTree(ICommonTreeNode superTree, ICommonTreeNode subTree) { var matchingRoots = MatchRoots(superTree, subTree); return(matchingRoots.Count > 0); }