spacepaste

  1.  
  2. $ ./trie_binary
  3. ----------------------------------------------------------------------->called init_aux() at line 348 from ../Shell/builtins/libstring.h
  4. ----------------------------------------------------------------------->called init_env() at line 327 from ../Shell/builtins/libstring.h
  5. ----------------------------------------------------------------------->called init_argX() at line 336 from ../Shell/builtins/libstring.h
  6. adding rule 1: segments [1, 0] root [10]
  7. adding rule 2: segments [0, 1] root [01]
  8. adding rule 3: root [00]
  9. segment.string = 1
  10. key = 1
  11. idx = 0
  12. pCrawl->count = 2
  13. pCrawl->idx[i] = 0
  14. pCrawl->idx[i] = 1
  15. final_match = true
  16. result = true
  17. segment.string = 0
  18. key = 0
  19. idx = 1
  20. pCrawl->count = 2
  21. pCrawl->idx[i] = 1
  22. pCrawl->idx[i] = 0
  23. final_match = true
  24. result = true
  25. 10 --- Present in trie
  26. segment.string = 0
  27. key = 0
  28. idx = 0
  29. pCrawl->count = 2
  30. pCrawl->idx[i] = 1
  31. pCrawl->idx[i] = 0
  32. final_match = true
  33. result = true
  34. segment.string = 1
  35. key = 1
  36. idx = 1
  37. pCrawl->count = 2
  38. pCrawl->idx[i] = 0
  39. pCrawl->idx[i] = 1
  40. final_match = true
  41. result = true
  42. 01 --- Present in trie
  43. segment.string = 0
  44. key = 0
  45. idx = 0
  46. pCrawl->count = 2
  47. pCrawl->idx[i] = 1
  48. pCrawl->idx[i] = 0
  49. final_match = true
  50. result = true
  51. segment.string = 0
  52. key = 0
  53. idx = 1
  54. pCrawl->count = 2
  55. pCrawl->idx[i] = 1
  56. pCrawl->idx[i] = 0
  57. final_match = true
  58. result = true
  59. 00 --- Present in trie
  60. $ cat ./trie_binary.c
  61. // C implementation of search and insert operations
  62. // on Trie
  63. #include <stdio.h>
  64. #include <stdlib.h>
  65. #include <string.h>
  66. #include <stdbool.h>
  67. // printf shorthand macros
  68. #include "../Shell/builtins/printfmacro.h"
  69. // string library and strying type identification
  70. #include "../Shell/builtins/regex_str.h"
  71. #define ARRAY_SIZE(a) sizeof(a)/sizeof(a[0])
  72. // Alphabet size (# of symbols)
  73. #define ALPHABET_SIZE (26)
  74. // Converts key current character into index
  75. // use only 'a' through 'z' and lower case
  76. #define CHAR_TO_INDEX(c) ((int)c - (int)'a')
  77. #define INT_TO_INDEX(c) ((int)c - (int)'0')
  78. // trie node
  79. struct TrieNode
  80. {
  81. struct TrieNode *children[ALPHABET_SIZE];
  82. int * idx;
  83. int count;
  84. // isEndOfWord is true if the node represents
  85. // end of a word
  86. bool isEndOfWord;
  87. };
  88. // Returns new trie node (initialized to NULLs)
  89. struct TrieNode *getNode(void)
  90. {
  91. struct TrieNode *pNode = NULL;
  92. pNode = (struct TrieNode *)malloc(sizeof(struct TrieNode));
  93. if (pNode)
  94. {
  95. int i;
  96. pNode->isEndOfWord = false;
  97. pNode->idx = NULL;
  98. pNode->count = 0;
  99. for (i = 0; i < ALPHABET_SIZE; i++)
  100. pNode->children[i] = NULL;
  101. }
  102. return pNode;
  103. }
  104. // If not present, inserts key into trie
  105. // If the key is prefix of trie node, just marks leaf node
  106. void insert(struct TrieNode *root, const char *key, int dest_idx)
  107. {
  108. int level;
  109. int length = strlen(key);
  110. int index;
  111. struct TrieNode *pCrawl = root;
  112. // pi(dest_idx)
  113. for (level = 0; level < length; level++)
  114. {
  115. // pi(level);
  116. // pc(key[level])
  117. str_new(ch);
  118. str_insert_char(ch, key[level]);
  119. if (ch.type & STR_TYPE_DIGIT) index = INT_TO_INDEX(key[level]);
  120. else if (ch.type & STR_TYPE_ALPHABETIC) index = CHAR_TO_INDEX(key[level]);
  121. str_free(ch)
  122. // pi(index)
  123. // pp(pCrawl->children[index])
  124. if (!pCrawl->children[index]) {
  125. pCrawl->children[index] = getNode();
  126. }
  127. if (level == length-1) {
  128. // pp(pCrawl->children[index])
  129. // pp(pCrawl->children[index]->idx)
  130. pCrawl->children[index]->count++;
  131. if (!pCrawl->children[index]->idx) {
  132. pCrawl->children[index]->idx = malloc(sizeof(int*)*pCrawl->children[index]->count);
  133. // pp(pCrawl->children[index]->idx)
  134. }
  135. else {
  136. pCrawl->children[index]->idx = realloc(pCrawl->children[index]->idx, sizeof(int*)*pCrawl->children[index]->count);
  137. }
  138. pCrawl->children[index]->idx[pCrawl->children[index]->count-1] = dest_idx;
  139. // pi(pCrawl->children[index]->idx[pCrawl->children[index]->count-1])
  140. }
  141. pCrawl = pCrawl->children[index];
  142. }
  143. // mark last node as leaf
  144. pCrawl->isEndOfWord = true;
  145. }
  146. // Returns true if key presents in trie, else false
  147. bool search(struct TrieNode *root, const char *key, int idx)
  148. {
  149. int level;
  150. int length = strlen(key);
  151. int index;
  152. struct TrieNode *pCrawl = root;
  153. // pi(idx);
  154. for (level = 0; level < length; level++)
  155. {
  156. str_new(ch);
  157. str_insert_char(ch, key[level]);
  158. if (ch.type & STR_TYPE_DIGIT) index = INT_TO_INDEX(key[level]);
  159. else if (ch.type & STR_TYPE_ALPHABETIC) index = CHAR_TO_INDEX(key[level]);
  160. str_free(ch)
  161. if (!pCrawl->children[index]) {
  162. index = CHAR_TO_INDEX('x');
  163. if (!pCrawl->children[index]) return false;
  164. }
  165. pCrawl = pCrawl->children[index];
  166. }
  167. ps(key);
  168. pi(idx);
  169. pi(pCrawl->count)
  170. bool final_match = false;
  171. for (int i = 0; i < pCrawl->count; i++) {
  172. pi(pCrawl->idx[i])
  173. if (pCrawl->idx[i] == idx) final_match = true;
  174. }
  175. pb(final_match)
  176. return (pCrawl != NULL && pCrawl->isEndOfWord && final_match);
  177. }
  178. // Returns true if key presents in trie, else false
  179. bool search_segmented(struct TrieNode *root, struct TrieNode *segments, const char *key)
  180. {
  181. int level;
  182. int length = strlen(key);
  183. int index;
  184. struct TrieNode *pCrawl = root;
  185. str_new(segment);
  186. int idx = 0;
  187. for (level = 0; level < length; level++)
  188. {
  189. str_insert_char(segment, key[level]);
  190. ps(segment.string);
  191. bool result = search(segments, segment.string, idx);
  192. pb(result);
  193. if (result) {
  194. str_reset(segment);
  195. idx++;
  196. }
  197. str_new(ch);
  198. str_insert_char(ch, key[level]);
  199. if (ch.type & STR_TYPE_DIGIT) index = INT_TO_INDEX(key[level]);
  200. else if (ch.type & STR_TYPE_ALPHABETIC) index = CHAR_TO_INDEX(key[level]);
  201. str_free(ch)
  202. if (!pCrawl->children[index]) {
  203. index = CHAR_TO_INDEX('x');
  204. if (!pCrawl->children[index]) return false;
  205. }
  206. pCrawl = pCrawl->children[index];
  207. }
  208. str_free(segment);
  209. return (pCrawl != NULL && pCrawl->isEndOfWord);
  210. }
  211. #define isp(root, segments, c) printf("%s --- %s\n", c, output[search_segmented(root, segments, c)] )
  212. // Driver
  213. int main()
  214. {
  215. char output[][32] = {"Not present in trie", "Present in trie"};
  216. struct TrieNode *root = getNode();
  217. struct TrieNode *segments = getNode();
  218. // Construct trie
  219. /* shall aim to be equivilant to this
  220. rule_1 ::= "1" "0";
  221. rule_2 ::= "0" "1";
  222. rule_3 ::= "0" "0";
  223. */
  224. // rule 1
  225. puts("adding rule 1: segments [1, 0] root [10]");
  226. insert(segments, "1", 0);
  227. insert(segments, "0", 1);
  228. insert(root, "10", 0);
  229. // rule 2
  230. puts("adding rule 2: segments [0, 1] root [01]");
  231. insert(segments, "0", 0);
  232. insert(segments, "1", 1);
  233. insert(root, "01", 0);
  234. puts("adding rule 3: root [00]"); // no segments, needs to confirm segment to rule isolation, currently this seems impossible in a trie
  235. insert(root, "00", 0);
  236. // Search for different keys
  237. isp(root, segments, "10");
  238. isp(root, segments, "01");
  239. isp(root, segments, "00");
  240. return 0;
  241. }
  242.