/// <summary> /// Creates a suffix tree for the given text. /// Make sure the last character in 'text' is unique; im using $.. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="text">The text.</param> /// <returns>if the argument 'text' is empty or null string, function returns null !!</returns> public static ISuffixTree Create <T>(string text) where T : IDictionary <char, ISuffixNode>, new() { var suffixImpl = SuffixTreeImpl <T> .Create(text); return(suffixImpl == null ? null : new SuffixTree() { Root = suffixImpl.Root, Text = suffixImpl.Text }); }
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); }
/// <summary> /// Creates a suffix tree for the given text. /// Make sure the last character in 'text' is unique; im using $.. /// </summary> /// <param name="text">The text.</param> /// <returns>if the argument 'text' is empty or null string, function returns null !!</returns> public static ISuffixTree Create(string text) { return(SuffixTreeImpl <Dictionary> .Create(text)); }
/// <summary> /// Creates a suffix tree for the given text. /// Make sure the last character in 'text' is unique; im using $.. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="text">The text.</param> /// <returns>if the argument 'text' is empty or null string, function returns null !!</returns> public static ISuffixTree Create <T>(string text) where T : IDictionary <char, ISuffixNode>, new() { return(SuffixTreeImpl <T> .Create(text)); }