Advertisement
rupek1995

dictionary

Apr 2nd, 2017
512
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.21 KB | None | 0 0
  1. /**
  2.  * Implements a dictionary's functionality.
  3.  */
  4.  
  5. #include <stdbool.h>
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <ctype.h>
  10.  
  11. #include "dictionary.h"
  12.  
  13. #define LONGEST_WORD (sizeof("pneumonoultramicroscopicsilicovolcanoconiosis"))
  14. #define ALPHABET_LENGTH 27
  15.  
  16. // defining trie
  17. typedef struct node
  18. {
  19.     bool is_word;
  20.     struct node *children[ALPHABET_LENGTH];
  21. } trie;
  22.  
  23. // prototyping
  24. void init_trie(void);
  25. void insert_word(char *word);
  26. bool destroy_trie(trie *curr_trie);
  27. int count_words_trie(trie *curr_trie);
  28.  
  29. // create a global root
  30. trie *root = NULL;
  31. // global word count
  32. int word_count = 0;
  33.  
  34. /**
  35.  * Returns true if word is in dictionary else false.
  36.  */
  37. bool check(const char *word)
  38. {
  39.     // variable for iterating through every letter of word, and a traversal pointer
  40.     int word_len = strlen(word), curr_letter;
  41.     trie *traversal = root;
  42.  
  43.     // go through every letter node for word until an empty node
  44.     for (int i = 0; i < word_len; i++)
  45.     {
  46.         // current letter index in trie array, if uppercase - calculate it for lowercase letter
  47.         if (word[i] < 96)
  48.             curr_letter = tolower(word[i]) % 97;
  49.         else
  50.             curr_letter = word[i] % 97;
  51.  
  52.         // if next letter's node is null - word is misspelled, else go to next node
  53.         if (traversal->children[curr_letter] == NULL)
  54.             return false;
  55.         else
  56.             traversal = traversal->children[curr_letter];
  57.     }
  58.  
  59.     if (traversal->is_word)
  60.         return true;
  61.     else
  62.         return false;
  63. }
  64.  
  65. /**
  66.  * Loads dictionary into memory. Returns true if successful else false.
  67.  */
  68. bool load(const char *dictionary)
  69. {
  70.     // create trie variable
  71.     init_trie();
  72.  
  73.     // open dictionary file
  74.     FILE *filein = fopen(dictionary, "r");
  75.     if (filein == NULL)
  76.     {
  77.         fprintf(stderr, "Could not open %s\n", dictionary);
  78.         return false;
  79.     }
  80.  
  81.     // read words into memory
  82.     char *read_buffer = malloc(LONGEST_WORD * sizeof(char));
  83.     // error check
  84.     if (read_buffer == NULL)
  85.     {
  86.         free(read_buffer);
  87.         unload();
  88.         return false;
  89.     }
  90.  
  91.     while (fscanf(filein, "%s", read_buffer) != EOF)
  92.         insert_word(read_buffer);
  93.        
  94.     // free memory allocs
  95.     free(read_buffer);
  96.     fclose(filein);
  97.  
  98.  
  99.     // return true if loaded
  100.     return true;
  101. }
  102.  
  103. /**
  104.  * Returns number of words in dictionary if loaded else 0 if not yet loaded.
  105.  */
  106. unsigned int size(void)
  107. {
  108.     int size = 0;
  109.     size += count_words_trie(root);
  110.     return size;
  111. }
  112.  
  113. /**
  114.  * Unloads dictionary from memory. Returns true if successful else false.
  115.  */
  116. bool unload()
  117. {
  118.     if (!destroy_trie(root))
  119.         return false;
  120.     else
  121.         return true;
  122. }
  123.  
  124. /**
  125.  * Creates a new trie
  126.  */
  127. void init_trie(void)
  128. {
  129.     root = malloc(sizeof(trie));
  130.     root->is_word = false;
  131. }
  132.  
  133. /**
  134.  * Inserts new word from dictionary into trie
  135.  */
  136. void insert_word(char *word)
  137. {
  138.     int word_len = strlen(word) + 1, curr_letter;
  139.     trie *traversal = root;
  140.  
  141.     for (int i = 0; i < word_len; i++)
  142.     {
  143.         // convert current letter/apostrophe from ascii alphabet value (96-122) to array-like (0-26) value
  144.         // if uppercase - calculate it for lowercase letter
  145.         if (word[i] < 96)
  146.             curr_letter = tolower(word[i]) % 97;
  147.         else
  148.             curr_letter = word[i] % 97;
  149.  
  150.         // if next letter node is empty - malloc it
  151.         if (traversal->children[curr_letter] == NULL)
  152.         {
  153.             traversal->children[curr_letter] = malloc(sizeof(trie));
  154.         }
  155.  
  156.         // travel to next letter in trie until end of word
  157.         if (word[i] != '\0')
  158.             traversal = traversal->children[curr_letter];
  159.     }
  160.  
  161.     traversal->is_word = true;
  162. }
  163.  
  164. bool destroy_trie(trie *curr_trie)
  165. {
  166.     bool success = false;
  167.     trie *traversal = curr_trie;
  168.  
  169.     // search parent for non-null node
  170.     for (int i = 0; i < ALPHABET_LENGTH; ++i)
  171.     {
  172.         // if found - search children for non-null node
  173.         if (traversal->children[i] != NULL)
  174.             destroy_trie(traversal->children[i]);
  175.     }
  176.  
  177.     free(traversal);
  178.     success = true;
  179.     return success;
  180. }
  181.  
  182. /**
  183.  * Count total words in trie
  184.  */
  185. int count_words_trie(trie *curr_trie)
  186. {
  187.     trie *traversal = curr_trie;
  188.  
  189.     // search parent for non-null node
  190.     for (int i = 0; i < ALPHABET_LENGTH; ++i)
  191.     {
  192.         // if found - search children for non-null node
  193.         if (traversal->children[i] != NULL)
  194.             count_words_trie(traversal->children[i]);
  195.     }
  196.  
  197.     if (traversal->is_word == true)
  198.         word_count++;
  199.  
  200.     return word_count;
  201. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement