public static string GetNodeSuffix(this ISuffixTree t, ISuffixNode p) { var sb = new StringBuilder(); GetNodeSuffixImpl(t, p, sb); return(sb.ToString()); }
/// <summary> /// Searches for specified text within the tree and returns the list of matching starting positions. /// </summary> /// <param name="text">The text.</param> /// <param name="matchList">The match list.</param> /// <returns></returns> public bool Search(string text, out List <int> matchList) { matchList = null; ISuffixNode found = null; int firstUnmached = -1; var matchNodeList = new List <ISuffixNode>(); int matchedOk = this.Search(text, ref matchNodeList, out found, out firstUnmached); if (matchedOk == text.Length) { matchList = new List <int>(); foreach (var n in matchNodeList) { matchList.Add(n.LeafNumber); } return(true); } else { return(false); } }
private static void GetNodeSuffixImpl(ISuffixTree t, ISuffixNode p, StringBuilder sb) { if (p.Parent != null) { GetNodeSuffixImpl(t, p.Parent, sb); int length = (p.IsLeaf ? t.Text.Length - 1 : p.Edge.End) - p.Edge.Start + 1; sb.Append(t.Text.Substring(p.Edge.Start, length)); } }
/// <summary> /// Determines whether [contains] [the specified text]. /// </summary> /// <param name="text">The text.</param> /// <returns> /// <c>true</c> if [contains] [the specified text]; otherwise, <c>false</c>. /// </returns> public bool Contains(string text) { ISuffixNode found = null; int firstUnmached = -1; List <ISuffixNode> matchList = null; int matchedOk = this.Search(text, ref matchList, out found, out firstUnmached); return(matchedOk == text.Length); }
public SuffixNode GetEdge(char startChar) { ISuffixNode child = null; if (this.Children.TryGetValue(startChar, out child)) { return((SuffixNode)child); } else { return(null); } }
private void VerifyInternal(ISuffixNode p) { if (p != null && !p.IsLeaf && p != this.Tree.Root) { Debug.Assert(p.Link != null); var thisSuffix = this.Tree.GetNodeSuffix(p); var linkSuffix = this.Tree.GetNodeSuffix(p.Link); Debug.Assert(thisSuffix.Length - 1 == linkSuffix.Length); Debug.Assert(thisSuffix.Substring(1).Equals(linkSuffix)); } }
private void verify(ISuffixNode suffixNode) { if (suffixNode != null && !suffixNode.IsLeaf && suffixNode != this.Tree.Root) { Debug.Assert(suffixNode.Link != null); var thisSuffix = this.Tree.GetNodeSuffix(suffixNode); var linkSuffix = this.Tree.GetNodeSuffix(suffixNode.Link); Debug.Assert(thisSuffix.Length - 1 == linkSuffix.Length); Debug.Assert(thisSuffix.Substring(1).Equals(linkSuffix)); } }
private void RunImpl(ISuffixNode p) { if (p.IsLeaf) { suffixes.Add(p.LeafNumber, p); } else { if (p.Parent != null) { internals.Add(p); VerifyInternal(p); } foreach (var kvp in p.Children) { RunImpl(kvp.Value); } } }
private void build(ISuffixNode suffixNode) { if (suffixNode != null) { if (suffixNode.IsLeaf) { suffixNodes.Add(suffixNode.LeafNumber, suffixNode); } else { if (suffixNode.Parent != null) { internalNodes.Add(suffixNode); verify(suffixNode); } foreach (var kvp in suffixNode.Children) { build(kvp.Value); } } } }
/// <summary> /// Searches for the specified text. /// </summary> /// <param name="text">The text.</param> /// <param name="matchingList">The matching list.</param> /// <param name="child">The child.</param> /// <param name="firstUnmachedEdgeIndex">First index of the unmached edge.</param> /// <returns>number of characters successfully matched</returns> private int Search(string text, ref List <ISuffixNode> matchingList, out ISuffixNode child, out int firstUnmachedEdgeIndex) { child = null; firstUnmachedEdgeIndex = -1; if (string.IsNullOrEmpty(text)) { return(0); } var parent = this.Root; int length = text.Length; int k = 0, e = -1; while (parent.Children.TryGetValue(text[k], out child)) { e = child.Edge.Start; if (child.IsLeaf) { // leaves haven't been fixed up Debug.Assert(child.Edge.End != -1); } int end = child.Edge.End; while (k < length && e <= end && text[k++] == this.Text[e++]) { } if (k < length && e > end) { //good so far, keep going.. parent = child; continue; } else { break; } } // did anything match? if (k <= 0) { return(0); } // did we agree on the last char? if (text[k - 1] == this.Text[e - 1]) { if (matchingList != null) { //find all leaves below and get your matching list.. var stack = new Stack <ISuffixNode>(); stack.Push(child); matchingList = new List <ISuffixNode>(); while (stack.Count > 0) { var p = stack.Pop(); if (p.IsLeaf) { matchingList.Add(p); } else { foreach (var c in p.Children) { stack.Push(c.Value); } } } } return(k); } else { //well, wish you luck next time.. firstUnmachedEdgeIndex = e - 1; return(k - 1); } }
/// <summary> /// Searches for the specified text. /// </summary> /// <param name="text">The text.</param> /// <param name="matchingList">The matching list.</param> /// <param name="child">The child.</param> /// <param name="unmatchedEdgeCursor">First index of the unmached edge.</param> /// <returns>number of characters successfully matched</returns> public MatchResult Match(string text) { if (string.IsNullOrEmpty(text)) { return(null); } var matchResult = new MatchResult() { MatchedCount = 0, InternNode = null, UnmatchedEdgeCursor = -1, MatchingSuffixes = null, }; var parent = this.Tree.Root; int length = text.Length; int k = 0, edgeCursor = -1; ISuffixNode child = null; while (parent.Children.TryGetValue(text[k], out child)) { int edgeEnd = child.Edge.End; edgeCursor = child.Edge.Start; while (k < length && edgeCursor <= edgeEnd && text[k++] == this.Tree.Text[edgeCursor++]) { } if (k < length && edgeCursor > edgeEnd) { parent = child; } else { break; } } if (k > 0) { matchResult.InternNode = child; var agreedOnLastChar = text[k - 1] == this.Tree.Text[edgeCursor - 1]; var stack = new Stack <ISuffixNode>(); stack.Push(child); while (stack.Count > 0) { var p = stack.Pop(); if (p.IsLeaf) { if (matchResult.MatchingSuffixes == null) { matchResult.MatchingSuffixes = new List <ISuffixNode>(); } matchResult.MatchingSuffixes.Add(p); } else { foreach (var c in p.Children) { stack.Push(c.Value); } } } if (!agreedOnLastChar) { matchResult.UnmatchedEdgeCursor = edgeCursor - 1; matchResult.MatchedCount = k - 1; } else { matchResult.MatchedCount = k; } } return(matchResult); }
private void verify(ISuffixNode suffixNode) { if (suffixNode != null && !suffixNode.IsLeaf && suffixNode != this.Tree.Root) { Debug.Assert(suffixNode.Link != null); var thisSuffix = this.Tree.GetNodeSuffix(suffixNode); var linkSuffix = this.Tree.GetNodeSuffix(suffixNode.Link); Debug.Assert(thisSuffix.Length - 1 == linkSuffix.Length); Debug.Assert(thisSuffix.Substring(1).Equals(linkSuffix)); } }
private void build(ISuffixNode suffixNode) { if (suffixNode != null) { if (suffixNode.IsLeaf) { suffixNodes.Add(suffixNode.LeafNumber, suffixNode); } else { if (suffixNode.Parent != null) { internalNodes.Add(suffixNode); verify(suffixNode); } foreach (var kvp in suffixNode.Children) { build(kvp.Value); } } } }