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