/// <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;
                }
            }
Beispiel #2
0
            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);
            }