spacepaste

  1.  
  2. // C implementation of search and insert operations
  3. // on Trie
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <stdbool.h>
  8. #define pi(x) printf("%s = %d\n", #x, x);
  9. #define pc(x) printf("%s = %c\n", #x, x);
  10. #define pp(x) printf("%s = %p\n", #x, x);
  11. #define ps(x) printf("%s = %s\n", #x, x);
  12. #define pb(x) printf("%s = %s\n", #x, x==true?"true":"false");
  13. struct regex_string_structure
  14. {
  15. char * string;
  16. int index;
  17. int len;
  18. int malloced;
  19. };
  20. struct regex_string
  21. {
  22. char * string;
  23. int index;
  24. int len;
  25. int malloced;
  26. };
  27. #define str_malloc_(y, z) \
  28. (y).string = malloc(z); \
  29. memset((y).string, 0, z); \
  30. (y).malloced = z; \
  31. (y).len = 0; \
  32. (y).index = 0;
  33. #define str_mallocr(y, z) \
  34. str_malloc_((y), z); \
  35. #define str_malloc(y, z) \
  36. struct regex_string y; \
  37. str_mallocr((y), z);
  38. #define str_new(str) \
  39. str_malloc(str, 1) \
  40. #define str_free_(y) \
  41. memset((y).string, 0, (y).malloced); \
  42. free((y).string); \
  43. (y).string = NULL; \
  44. (y).malloced = 0; \
  45. (y).len = 0; \
  46. (y).index = 0; \
  47. #define str_free(y) \
  48. { \
  49. str_free_((y)); \
  50. }
  51. #define str_reset_(str) { \
  52. str_free_((str)) \
  53. str_malloc_((str), 1) \
  54. }
  55. #define str_reset(str) { \
  56. str_reset_((str)) \
  57. }
  58. #define str_realloc(y, z) \
  59. (y).string = realloc((y).string, z); \
  60. if ((y).malloced < z) { \
  61. memset((y).string+(y).malloced, 0, (z)-(y).malloced); \
  62. } \
  63. (y).malloced = z;
  64. #define str_insert_char(str, ch) { \
  65. str_realloc((str), (str).malloced+2); \
  66. (str).string[(str).index] = ch; \
  67. (str).index++; \
  68. (str).string[(str).index] = 0; \
  69. (str).len = strlen((str).string); \
  70. }
  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. // trie node
  78. struct TrieNode
  79. {
  80. struct TrieNode *children[ALPHABET_SIZE];
  81. int idx;
  82. // isEndOfWord is true if the node represents
  83. // end of a word
  84. bool isEndOfWord;
  85. };
  86. // Returns new trie node (initialized to NULLs)
  87. struct TrieNode *getNode(int idx)
  88. {
  89. struct TrieNode *pNode = NULL;
  90. pNode = (struct TrieNode *)malloc(sizeof(struct TrieNode));
  91. if (pNode)
  92. {
  93. int i;
  94. pNode->isEndOfWord = false;
  95. pNode->idx = idx;
  96. for (i = 0; i < ALPHABET_SIZE; i++)
  97. pNode->children[i] = NULL;
  98. }
  99. return pNode;
  100. }
  101. // If not present, inserts key into trie
  102. // If the key is prefix of trie node, just marks leaf node
  103. void insert(struct TrieNode *root, const char *key, int dest_idx)
  104. {
  105. int level;
  106. int length = strlen(key);
  107. int index;
  108. struct TrieNode *pCrawl = root;
  109. for (level = 0; level < length; level++)
  110. {
  111. index = CHAR_TO_INDEX(key[level]);
  112. if (!pCrawl->children[index])
  113. pCrawl->children[index] = getNode(dest_idx);
  114. else pCrawl->children[index]->idx = dest_idx;
  115. pCrawl = pCrawl->children[index];
  116. }
  117. // mark last node as leaf
  118. pCrawl->isEndOfWord = true;
  119. }
  120. // Returns true if key presents in trie, else false
  121. bool search(struct TrieNode *root, const char *key, int idx)
  122. {
  123. int level;
  124. int length = strlen(key);
  125. int index;
  126. struct TrieNode *pCrawl = root;
  127. pi(idx);
  128. for (level = 0; level < length; level++)
  129. {
  130. index = CHAR_TO_INDEX(key[level]);
  131. if (!pCrawl->children[index]) {
  132. index = CHAR_TO_INDEX('x');
  133. if (!pCrawl->children[index]) return false;
  134. }
  135. pCrawl = pCrawl->children[index];
  136. }
  137. pi(pCrawl->idx);
  138. return (pCrawl != NULL && pCrawl->isEndOfWord && pCrawl->idx == idx);
  139. }
  140. // Returns true if key presents in trie, else false
  141. bool search_segmented(struct TrieNode *root, struct TrieNode *segments, const char *key)
  142. {
  143. int level;
  144. int length = strlen(key);
  145. int index;
  146. struct TrieNode *pCrawl = root;
  147. str_new(segment);
  148. int idx = 0;
  149. for (level = 0; level < length; level++)
  150. {
  151. str_insert_char(segment, key[level]);
  152. ps(segment.string);
  153. pb(search(segments, segment.string, idx));
  154. if (search(segments, segment.string, idx)) {
  155. str_reset(segment);
  156. idx++;
  157. }
  158. index = CHAR_TO_INDEX(key[level]);
  159. if (!pCrawl->children[index]) {
  160. index = CHAR_TO_INDEX('x');
  161. if (!pCrawl->children[index]) return false;
  162. }
  163. pCrawl = pCrawl->children[index];
  164. }
  165. str_free(segment);
  166. return (pCrawl != NULL && pCrawl->isEndOfWord);
  167. }
  168. #define isp(root, segments, c) printf("%s --- %s\n", c, output[search_segmented(root, segments, c)] )
  169. // Driver
  170. int main()
  171. {
  172. char output[][32] = {"Not present in trie", "Present in trie"};
  173. struct TrieNode *root = getNode(0);
  174. struct TrieNode *segments = getNode(0);
  175. // Construct trie
  176. insert(segments, "0011", 0);
  177. insert(segments, "001", 1);
  178. insert(segments, "0", 2);
  179. insert(root, "00110010", 0);
  180. // Search for different keys
  181. isp(root, segments, "00110010");
  182. return 0;
  183. }
  184.