예제 #1
0
        private void Traverse(Node node, Action<string> action, string s)
        {
            if (node == null)
                return;

            Traverse(node.Left, action, s);
            if (node.WordEnd)
                action.Invoke(s);
            else
                Traverse(node.Center, action, s + node.Char);
            Traverse(node.Right, action, s);
        }
예제 #2
0
        /// <summary>
        /// Performs a matching search.
        /// </summary>
        /// <code>
        /// void pmsearch(Tptr p, char *s)
        /// {
        ///     if (!p) return;
        ///     nodecnt++;
        ///     if (*s == '.' || *s &lt; p-&gt;splitchar)
        ///         pmsearch(p-&gt;lokid, s);
        ///     if (*s == '.' || *s == p-&gt;splitchar)
        ///         if (p-&gt;splitchar && *s)
        ///             pmsearch(p-&gt;eqkid, s+1);
        ///     if (*s == 0 && p-&gt;splitchar == 0)
        ///         srcharr[srchtop++] = (char *) p-&gt;eqkid;
        ///     if (*s == '.' || *s &gt; p-&gt;splitchar)
        ///         pmsearch(p-&gt;hikid, s);
        /// }
        /// </code>
        /// <param name="s"></param>
        /// <param name="substr"></param>
        /// <param name="pos"></param>
        /// <param name="node"></param>
        /// <param name="matches"></param>
        /// <param name="limit"></param>
        private void Matches(string s, string substr, int pos, Node node, List<string> matches, int limit)
        {
            if (node == null || matches.Count >= limit)
                return;
            Nodes++;

            char c = pos == s.Length ? default(char) : s[pos];
            if (WildcardMatchLeft(c, node.Char) || c < node.Char)
                Matches(s, substr, pos, node.Left, matches, limit);

            if (WildcardMatch(c, node.Char) || c == node.Char)
                Matches(s, substr + node.Char, pos + 1, node.Center, matches, limit);

            if (c == default(char) && node.WordEnd)
                matches.Add(substr);

            if (WildcardMatchRight(c, node.Char) || c > node.Char)
                Matches(s, substr, pos, node.Right, matches, limit);
        }
예제 #3
0
        /// <summary>
        /// Finds matches using a nearest search.
        /// </summary>
        /// <code>
        /// void nearsearch(Tptr p, char *s, int d)
        /// {
        ///     if (!p || d &lt; 0) return;
        ///     nodecnt++;
        ///     if (d &gt; 0 || *s &lt; p-&gt;splitchar)
        ///         nearsearch(p->lokid, s, d);
        ///     if (p-&gt;splitchar == 0) {
        ///         if ((int) strlen(s) &lt;= d)
        ///         srcharr[srchtop++] = (char *) p-&gt;eqkid;
        ///     }
        ///     else
        ///         nearsearch(p->eqkid,
        ///                    *s ? s+1:s,
        ///                    (*s==p->splitchar) ? d:d-1);
        ///     if (d &gt; 0 || *s &gt; p->splitchar)
        ///         nearsearch(p->hikid, s, d);
        /// }
        /// </code>
        /// <param name="s"></param>
        /// <param name="substr"></param>
        /// <param name="pos"></param>
        /// <param name="node"></param>
        /// <param name="matches"></param>
        /// <param name="limit"></param>
        /// <param name="depth"></param>
        private void NearSearch(string s, string substr, int pos, Node node, List<string> matches, int limit, int depth)
        {
            if (node == null || matches.Count >= limit || depth < 0)
                return;

            Nodes++;

            char c = default(char);
            if (pos < s.Length)
                c = s[pos];

            if (depth > 0 || c < node.Char)
                NearSearch(s, substr, pos, node.Left, matches, limit, depth);

            if (node.WordEnd)
            {
                if (s.Length - pos <= depth)
                    matches.Add(substr);
            }
            else
            {
                int newDepth = c == node.Char ? depth : depth - 1;
                if (c != default(char))
                    NearSearch(s, substr + node.Char, pos + 1, node.Center, matches, limit, newDepth);
                else
                    NearSearch(s, substr + node.Char, pos, node.Center, matches, limit, newDepth);
            }

            if (depth > 0 || c > node.Char)
                NearSearch(s, substr, pos, node.Right, matches, limit, depth);
        }
예제 #4
0
        private static Node Add(string s, int pos, ref Node node)
        {
            char c = pos == s.Length ? default(char) : s[pos];
            if (node == null)
                node = new Node { Char = c, WordEnd = false };

            if (c < node.Char)
                node.Left = Add(s, pos, ref node.Left);
            else if (c == node.Char)
            {
                if (pos != s.Length)
                    node.Center = Add(s, pos + 1, ref node.Center);
                else
                    node.WordEnd = true;
            }
            else
                node.Right = Add(s, pos, ref node.Right);

            return node;
        }