Beispiel #1
0
        public static string GetNodeSuffix(this ISuffixTree t, ISuffixNode p)
        {
            var sb = new StringBuilder();

            GetNodeSuffixImpl(t, p, sb);
            return(sb.ToString());
        }
Beispiel #2
0
            /// <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);
                }
            }
Beispiel #3
0
        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));
            }
        }
Beispiel #4
0
            /// <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);
            }
Beispiel #5
0
                public SuffixNode GetEdge(char startChar)
                {
                    ISuffixNode child = null;

                    if (this.Children.TryGetValue(startChar, out child))
                    {
                        return((SuffixNode)child);
                    }
                    else
                    {
                        return(null);
                    }
                }
Beispiel #6
0
        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));
            }
        }
Beispiel #7
0
            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));
                }
            }
Beispiel #8
0
        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);
                }
            }
        }
Beispiel #9
0
            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);
                        }
                    }
                }
            }
Beispiel #10
0
            /// <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);
                }
            }
Beispiel #11
0
            /// <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);
                        }
                    }
                }
            }