Guest User

Trie for SO qn http://stackoverflow.com/questions/17758452/t

a guest
Jul 20th, 2013
163
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.53 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #define NRALPHA 26
  6. #define VEC_INIT_SZ 64
  7.  
  8. struct Vec {
  9.     char *buf;
  10.     int nrChars;
  11.     int capacity;
  12. };
  13.  
  14. struct Vec *vec_new()
  15. {
  16.     struct Vec *v = (struct Vec *)calloc(1, sizeof(struct Vec));
  17.     v->buf = (char *)calloc(VEC_INIT_SZ, sizeof(char));
  18.     v->capacity = VEC_INIT_SZ;
  19.     return v;
  20. }
  21.  
  22. void vec_free(struct Vec *v)
  23. {
  24.     if (v) {
  25.         if (v->buf) {
  26.             free(v->buf);
  27.         }
  28.         free(v);
  29.     }
  30. }
  31.  
  32. int vec_increase_size(struct Vec *v)
  33. {
  34.     int newCap;
  35.     char *tmpbuf;
  36.     if (v->nrChars+1 >= v->capacity) {
  37.         newCap = v->capacity * 2;
  38.         tmpbuf = (char *)realloc(v->buf, newCap);
  39.         if (!tmpbuf) {
  40.             return 0;
  41.         }
  42.         v->buf = tmpbuf;
  43.         v->capacity = newCap;
  44.         return 1;
  45.     } else {
  46.         return 1;
  47.     }
  48. }
  49.  
  50. void vec_print(struct Vec *v)
  51. {
  52.     if (v->nrChars >= 0) {
  53.         v->buf[v->nrChars] = 0;
  54.         printf("%s\n", v->buf);
  55.     }
  56. }
  57.  
  58. void vec_put_char(struct Vec *v, char ch)
  59. {
  60.     v->buf[v->nrChars++] = ch;
  61. }
  62.  
  63. void vec_pop_char(struct Vec *v)
  64. {
  65.     if (v->nrChars > 0) {
  66.         v->nrChars--;
  67.     }
  68. }
  69.  
  70. void vec_clear(struct Vec *v)
  71. {
  72.     v->nrChars = 0;
  73. }
  74.  
  75. struct trie {
  76.     int val;
  77.     struct trie *alpha[NRALPHA];
  78. };
  79.  
  80. struct trie *trie_new()
  81. {
  82.     return (struct trie *)calloc(1, sizeof(struct trie));
  83. }
  84.  
  85. struct trie *trie_insert(struct trie *root, char *input)
  86. {
  87.     int idx;
  88.     if (!input) {
  89.         return root;
  90.     }
  91.     if (root == NULL) {
  92.         root = (struct trie *)calloc(1, sizeof(struct trie));
  93.     }
  94.     if (*input == '\0') {
  95.         // leaves have root->val set to 1
  96.         root->val = 1;
  97.     } else {
  98.         // carry on insertion
  99.         idx = *input - 'a';
  100.         root->alpha[idx] = trie_insert(root->alpha[idx], input+1);
  101.     }
  102.     return root;
  103. }
  104.  
  105. // deletes the entire trie from root
  106. void trie_free(struct trie *root)
  107. {
  108.     int i;
  109.     if (root) {
  110.         for (i = 0; i < NRALPHA; i++) {
  111.             trie_free(root->alpha[i]);
  112.         }
  113.         free(root);
  114.     }
  115. }
  116.  
  117. // prints the trie depth first
  118. void trie_print(struct trie *root, struct Vec *v)
  119. {
  120.     int i;
  121.     if (root) {
  122.         // reach a string, just print
  123.         if (root->val) {
  124.             vec_print(v);
  125.         }
  126.         if (!vec_increase_size(v)) {
  127.             // out of memory
  128.             return;
  129.         }
  130.         for (i = 0; i < NRALPHA; i++) {
  131.             if (root->alpha[i]) {
  132.                 vec_put_char(v, 'a' + i);
  133.                 trie_print(root->alpha[i], v);
  134.                 vec_pop_char(v);
  135.             }
  136.         }
  137.     } else {
  138.         return;
  139.     }
  140. }
  141.  
  142. struct trie *trie_delete(struct trie *root, char *s)
  143. {
  144.     int i, idx, reap = 0;
  145.     if (!root || !s) {
  146.         return root;
  147.     }
  148.     if (!*s && root->val) {
  149.         // delete this string, and mark node as deletable
  150.         root->val = 0;
  151.         reap = 1;
  152.     } else {
  153.         // more characters carry on
  154.         idx = *s - 'a';
  155.         if (root->alpha[idx]) {
  156.             root->alpha[idx] = trie_delete(root->alpha[idx], s+1);
  157.             if (!root->alpha[idx]) {
  158.                 // child node deleted, set reap = 1
  159.                 reap = 1;
  160.             }
  161.         }
  162.     }
  163.     // We can delete this if both:
  164.     // 1. reap is set to 1, which is only possible if either:
  165.     //    a. we are now at the end of the string and root->val used
  166.     //       to be 1, but is now set to 0
  167.     //    b. the child node has been deleted
  168.     // 2. The string ending at the current node is not inside the trie,
  169.     //    so root->val = 0
  170.     if (reap && !root->val) {
  171.         for (i = 0; i < NRALPHA; i++) {
  172.             if (root->alpha[i]) {
  173.                 reap = 0;
  174.                 break;
  175.             }
  176.         }
  177.         // no more children, delete this node
  178.         if (reap) {
  179.             trie_free(root);
  180.             root = NULL;
  181.         }
  182.     }
  183.     return root;
  184. }
  185.  
  186. int main()
  187. {
  188.     struct Vec *v = vec_new();
  189.     struct trie *root = trie_new();
  190.     // NOTE: max 120 chars including "ins " and "del "
  191.     char buf[121];
  192.     while (fgets(buf, sizeof(buf), stdin)) {
  193.         buf[strlen(buf)-1] = '\0';
  194.         if (!strncmp(buf, "ins ", 4)) {
  195.             root = trie_insert(root, buf+4);
  196.         } else if (!strncmp(buf, "del ", 4)) {
  197.             root = trie_delete(root, buf+4);
  198.         }
  199.         vec_clear(v);
  200.         printf("words in trie:\n");
  201.         trie_print(root, v);
  202.     }
  203.     trie_free(root);
  204.     vec_free(v);
  205.     return 0;
  206. }
Add Comment
Please, Sign In to add comment