private int GetEdgeLength(IEdgeLabel e) { return((e.End != -1 ? e.End : this.CurrentPhase - 1) - e.Start + 1); }
public static SuffixTreeImpl <ChildrenCollectionType> Create(string text) { if (string.IsNullOrEmpty(text)) { return(null); } var tree = new SuffixTreeImpl <ChildrenCollectionType>(text); var root = tree.theRoot; var deep = root.AddEdge(tree.Text, 0, -1); deep.SetLeaf(0); SuffixNode prevExtEnd = deep; int lastCreatedLeaf = -1; int m = text.Length; for (int i = 1; i < m; i++) { tree.CurrentPhase = i; bool skipRemaining = false; SuffixNode internCreatedPrevExt = null; int j = (lastCreatedLeaf == -1) ? 1 : lastCreatedLeaf; for (; j < i && !skipRemaining; j++) { IEdgeLabel[] edges = null; SuffixNode found = null; int edgecursor = -1; bool matchEndedAtNode; if (j == lastCreatedLeaf && j > 1) { if (!prevExtEnd.IsLeaf) { edges = new IEdgeLabel[] { 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 IEdgeLabel[] { 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); }