private SuffixNode TraverseEdge(SuffixNode parent, int matchingStart) { SuffixNode child = parent.GetEdge(this.GetCharFromIndex(matchingStart)); if (child == null) { throw new ApplicationException("unexpected!"); } return(child); }
private SuffixNode TraverseEdge(SuffixNode parent, int matchingStart) { SuffixNode child = parent.GetEdge(this.GetCharFromIndex(matchingStart)); if (child != null) { return(child); } else { throw new ArgumentException("invalid argument", "matchingStart"); } }
public static SuffixTreeImpl <ChildrenCollectionType> Create(string text) { if (string.IsNullOrEmpty(text)) { return(null); } var tree = new SuffixTreeImpl <ChildrenCollectionType>(); tree.Text = text; var root = tree.theRoot; int m = text.Length; var deep = root.AddEdge(tree.Text, 0, -1); deep.SetLeaf(0); SuffixNode prevExtEnd = deep; int lastCreatedLeaf = -1; for (int i = 1; i < m; i++) { tree.CurrentPhase = i; bool skipRemaining = false; SuffixNode internCreatedPrevExt = null; for (int j = 1; j < i && !skipRemaining; j++) { if (j < lastCreatedLeaf) { continue; } List <EdgeLabel> edges = null; SuffixNode found = null; int edgecursor = -1; bool matchEndedAtNode; if (j == lastCreatedLeaf && j > 1) { if (!prevExtEnd.IsLeaf) { edges = new List <EdgeLabel>(new EdgeLabel[] { EdgeLabel.Create(i - 1, i - 1) }); matchEndedAtNode = tree.Match(prevExtEnd, edges, out found, out edgecursor); } else { found = prevExtEnd; matchEndedAtNode = true; } } if (found == null) { SuffixNode target = null; if (tree.PreMatch(prevExtEnd, out target, out edges)) { edges = new List <EdgeLabel>(new EdgeLabel[] { EdgeLabel.Create(j, i - 1) }); matchEndedAtNode = tree.Match(tree.theRoot, edges, out found, out edgecursor); } else { if (edges != null) { matchEndedAtNode = tree.Match(target, edges, out found, out edgecursor); } else { found = target; matchEndedAtNode = true; } } } else { matchEndedAtNode = true; } if (!matchEndedAtNode) { if (tree.Text[edgecursor] == tree.Text[i]) { skipRemaining = true; break; } else { var foundParent = found.Parent; // there's no node here .. better create one.. foundParent.RemoveEdge(tree.GetCharFromIndex(found.Edge.Start)); // create new node.. var internalNode = foundParent.AddEdge(tree.Text, found.Edge.Start, edgecursor - 1); // massage old node and add it back.. found.Parent = internalNode; found.Edge.Start = edgecursor; internalNode.AddEdge(tree.Text, found); // fix up links if we need to .. if (internCreatedPrevExt != null) { internCreatedPrevExt.Link = internalNode; } internCreatedPrevExt = internalNode; // create a new leaf and hang it here.. var newLeaf = internalNode.AddEdge(tree.Text, i, -1); newLeaf.SetLeaf(j); lastCreatedLeaf = j; prevExtEnd = internalNode; } } else { if (found.IsLeaf) { prevExtEnd = found; } else { if (internCreatedPrevExt != null) { internCreatedPrevExt.Link = found; } internCreatedPrevExt = found.Link == null ? found : null; if (found.GetEdge(tree.GetCharFromIndex(i)) == null) { var newLeaf = found.AddEdge(tree.Text, i, -1); newLeaf.SetLeaf(j); lastCreatedLeaf = j; prevExtEnd = found; } else { skipRemaining = true; break; } } } } if (!skipRemaining) { var parent = root; var child = parent.GetEdge(tree.GetCharFromIndex(i)); if (child == null) { var newLeaf = parent.AddEdge(tree.Text, i, -1); newLeaf.SetLeaf(i); lastCreatedLeaf = i; prevExtEnd = newLeaf; } if (internCreatedPrevExt != null) { internCreatedPrevExt.Link = parent; internCreatedPrevExt = null; } } } tree.FixupLeaves(tree.theRoot, tree.Text.Length - 1); return(tree); }