/// <summary> /// Traverse the suffix tree, following the longest path from the root that matches a prefix of words[wordNum]. /// This allows the caller to skip over these duplicate characters, and process only the part of the coming word. /// </summary> /// <param name="active">The current active suffix</param> /// <param name="endIndex">The number of characters skipped</param> /// <param name="wordNum">The index of the current word begin processed</param> /// <seealso cref="http://www.cs.uku.fi/~kilpelai/BSA05/lectures/slides08.pdf"> /// The first 10 slides of this slideshow by Pekka Kilpeläinen /// have useful tips on creating a generalized suffix tree. /// </seealso> /// <remarks> /// TODO: Note: The following method is WORK IN PROGRESS, and does not yet work. /// </remarks> private void skipDuplicateInitialSubstring(ref GstSuffix active, ref int endIndex, int wordNum) { GstNode curNode = root; GstEdge nextEdge = null; GstEdge curEdge = null; // Traverse matching edges while ( (endIndex < wordDict[wordNum].Length) && ((nextEdge = curNode.GetChildEdge(GetWordChar(wordNum, endIndex))) != null) ) { int strLen = nextEdge.Span(0) + 1; // edgeStr = String in next edge string edgeStr = nextEdge.GetText(); // wordStr = next segment of upcoming word that corresponds to edgeStr string wordStr = wordDict[wordNum].Substring(endIndex, Math.Min(strLen, wordDict[wordNum].Length - endIndex)); bool foundMismatch = false; int numCharsMatched = 0; // Traverse matching characters within edge for (int i = 0; i < strLen; i++) { if (edgeStr[i] == wordStr[i]) { numCharsMatched++; } else { foundMismatch = true; break; } } if (foundMismatch) { GstUtil.WriteLine(GstVerbosityLevel.Verbose, String.Format( " skipDuplicateInitialSubstring: Word #{0:d} does not cover existing edge #{1:d}", wordNum, nextEdge.Id)); active.OriginNode = nextEdge.ParentNode; active.EndIndex = active.BeginIndex; break; } else { nextEdge.SetBeginIndex(wordNum, endIndex); nextEdge.SetEndIndex(wordNum, endIndex + strLen - 1); GstUtil.WriteLine(GstVerbosityLevel.Verbose, String.Format( " skipDuplicateInitialSubstring: Word #{0:d} covers existing edge #{1:d} ({2:s})", wordNum, nextEdge.Id, nextEdge.ToString(wordNum))); active.OriginNode = nextEdge.ChildNode; active.BeginIndex += numCharsMatched; active.EndIndex = active.BeginIndex; } endIndex += numCharsMatched; // Set up next iteration of loop curEdge = nextEdge; curNode = curEdge.ChildNode; } }
public void MoveFromTo(GstNode oldParentNode, char oldFirstChar, GstNode newParentNode, char newFirstChar) { GstEdge self = oldParentNode.GetChildEdge(oldFirstChar); if (self != this) { throw new ArgumentException("Error: MoveTo called with incorrect parent node and/or first char arguments"); } oldParentNode.RemoveChildEdge(oldFirstChar); newParentNode.AddChildEdge(newFirstChar, this); }