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); }
/// <summary> /// Performs a matching search. /// </summary> /// <code> /// void pmsearch(Tptr p, char *s) /// { /// if (!p) return; /// nodecnt++; /// if (*s == '.' || *s < p->splitchar) /// pmsearch(p->lokid, s); /// if (*s == '.' || *s == p->splitchar) /// if (p->splitchar && *s) /// pmsearch(p->eqkid, s+1); /// if (*s == 0 && p->splitchar == 0) /// srcharr[srchtop++] = (char *) p->eqkid; /// if (*s == '.' || *s > p->splitchar) /// pmsearch(p->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); }
/// <summary> /// Finds matches using a nearest search. /// </summary> /// <code> /// void nearsearch(Tptr p, char *s, int d) /// { /// if (!p || d < 0) return; /// nodecnt++; /// if (d > 0 || *s < p->splitchar) /// nearsearch(p->lokid, s, d); /// if (p->splitchar == 0) { /// if ((int) strlen(s) <= d) /// srcharr[srchtop++] = (char *) p->eqkid; /// } /// else /// nearsearch(p->eqkid, /// *s ? s+1:s, /// (*s==p->splitchar) ? d:d-1); /// if (d > 0 || *s > 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); }
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; }