Advertisement
Guest User

Untitled

a guest
Aug 3rd, 2015
173
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.27 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3.  
  4. namespace WildRide.Utils
  5. {
  6. public class PrefixTree<T>
  7. {
  8. private readonly Node _root;
  9.  
  10. public PrefixTree()
  11. {
  12. _root = new Node();
  13. }
  14.  
  15. public void Insert(string key, T data)
  16. {
  17. Node.Add(_root, new Substring(key), data);
  18. }
  19.  
  20. public int Count()
  21. {
  22. int count = 0;
  23. Node.Count(_root, ref count);
  24. return count;
  25. }
  26.  
  27. public IEnumerable<T> Find(string key)
  28. {
  29. Node node;
  30. if (Node.Find(_root, new Substring(key), out node))
  31. {
  32. return Node.GetData(node);
  33. }
  34. return null;
  35. }
  36.  
  37. private struct Substring
  38. {
  39. public Substring(string str) :
  40. this(str, 0, str.Length)
  41. {
  42. }
  43.  
  44. public Substring(string str, int start, int len)
  45. {
  46. String = str;
  47. Start = start;
  48. Length = len;
  49. }
  50.  
  51. public readonly int Start;
  52. public readonly int Length;
  53. public readonly string String;
  54.  
  55. public int StartsWith(Substring otherStr)
  56. {
  57. int pos;
  58. int len = Math.Min(this.Length, otherStr.Length);
  59. for (pos = 0; pos < len; ++pos)
  60. if (otherStr.String[pos + otherStr.Start] != this.String[pos + this.Start])
  61. break;
  62. return pos;
  63. }
  64.  
  65. public override string ToString()
  66. {
  67. return String.Substring(Start, Length);
  68. }
  69. }
  70.  
  71. private class Node
  72. {
  73. public Node() :
  74. this(default(Substring))
  75. {
  76. }
  77.  
  78. private Node(Substring key, T data = default(T))
  79. {
  80. _key = key;
  81. _data = data;
  82. _children = new Dictionary<char, Node>();
  83. }
  84.  
  85. private readonly Dictionary<char, Node> _children;
  86. private T _data;
  87. private Substring _key;
  88.  
  89. internal static void Add(Node node, Substring key, T data)
  90. {
  91. if (key.Length == 0)
  92. {
  93. node._data = data;
  94. return;
  95. }
  96.  
  97. Node child;
  98. if (node._children.TryGetValue(key.String[key.Start], out child))
  99. {
  100. int keyPos = child._key.StartsWith(key);
  101. if (keyPos == child._key.Length)
  102. {
  103. Add(child, new Substring(key.String, key.Start + keyPos, key.Length - keyPos), data);
  104. return;
  105. }
  106. if (keyPos > 0)
  107. {
  108. Node newRoot = new Node(new Substring(child._key.String, child._key.Start, keyPos));
  109. child._key = new Substring(child._key.String, child._key.Start + keyPos,
  110. child._key.Length - keyPos);
  111. newRoot._children.Add(child._key.String[child._key.Start], child);
  112. node._children[newRoot._key.String[newRoot._key.Start]] = newRoot;
  113. Add(newRoot, new Substring(key.String, key.Start + keyPos, key.Length - keyPos), data);
  114. }
  115. }
  116. else
  117. {
  118. Node n = new Node(key, data);
  119. node._children.Add(key.String[key.Start], n);
  120. }
  121. }
  122.  
  123. internal static bool Find(Node node, Substring key, out Node result)
  124. {
  125. if (key.Length == 0)
  126. {
  127. result = node;
  128. return true;
  129. }
  130.  
  131. Node child;
  132. if (node._children.TryGetValue(key.String[key.Start], out child))
  133. {
  134. int keyPos = child._key.StartsWith(key);
  135. if (keyPos == child._key.Length)
  136. {
  137. return Find(child, new Substring(key.String, key.Start + keyPos, key.Length - keyPos), out result);
  138. }
  139. if (keyPos > 0 && (key.Length - keyPos) == 0)
  140. {
  141. result = child;
  142. return true;
  143. }
  144. }
  145.  
  146. result = default(Node);
  147. return false;
  148. }
  149.  
  150. internal static IEnumerable<T> GetData(Node node)
  151. {
  152. if (node._data != null)
  153. yield return node._data;
  154. foreach (var child in node._children)
  155. {
  156. foreach (T data in GetData(child.Value))
  157. yield return data;
  158. }
  159. }
  160.  
  161. internal static void Count(Node node, ref int count)
  162. {
  163. count++;
  164. foreach (var child in node._children)
  165. {
  166. Count(child.Value, ref count);
  167. }
  168. }
  169.  
  170. public override string ToString()
  171. {
  172. return _key.ToString();
  173. }
  174. }
  175. }
  176. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement