Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * Implements a dictionary's functionality.
- */
- #include <stdio.h> // needed for printf
- #include <stdlib.h> // needed for malloc
- #include <stdbool.h> // needed for bool
- #include <ctype.h> //needed for isalpha, isupper, islower
- #include <string.h> // needed for strlen
- #include "dictionary.h"
- #include "speller.c" // NEVER, EVER DO THIS!! .c files should not be included!! :)
- // Create node data type
- typedef struct node
- {
- bool is_word; // how do I default this to false??? YOU DON'T. NOT HERE.
- struct node *children[27];
- }
- node;
- // Declare global variables
- node *root = NULL; // accessed by check, load, and unload
- unsigned int dict_wordCount; // accessed by load, size
- const char *dictionary; // accessed by load, size WHY THIS? YOU DON'T NEED THIS
- /**
- * Returns true if word is in dictionary else false.
- */
- bool check(const char *word)
- {
- // declare variables
- int gateCheck; // which gate number to check for each character in the word being spellchecked
- node *cursor = root; // a cursor to move through the trie
- // for each character in the word being checked
- for (int i = 0; i <= strlen(word); i++)
- {
- // if the character is a letter or apostrophe, translate the character's ASCII number to its corresponding gate number
- if (!word[i] == 0)
- {
- // if the character is a capital letter
- if (isupper(word[i]))
- {
- gateCheck = (word[i] - 65);
- }
- // if the character is a miniscule letter
- else if (islower(word[i]))
- {
- gateCheck = (word[i] - 97);
- }
- // if the character is an apostrophe
- else if (word[i] == 39)
- {
- gateCheck = 26;
- }
- // check the character's corresponding gate number
- if (cursor->children[gateCheck] == NULL) // if the gate of that character is closed
- {
- return false; // the word is mispelled
- }
- else // if the gate of that character is open
- {
- *cursor = *cursor->children[gateCheck]; // move down the gate to the next character
- /*
- *******************************************************************************
- WHY ARE YOU DEREFERENCING HERE?
- YOU WANT TO MOVE THE POINTER AND NOT CHANGE THE VALUE STORED IN THE POINTER
- *******************************************************************************
- */
- }
- }
- // the character is a '/0' a.k.a. NUL to indicate the end of the word
- else
- {
- if (cursor->is_word == false) // if the dictionary does not indicate the end of a word
- {
- return false; // the word is mispelled
- }
- }
- }
- // the word is spelled correctly
- return true;
- }
- /**
- * Loads dictionary into memory. Returns true if successful else false.
- */
- bool load(const char *dictionary)
- {
- // Open dictionary file
- FILE *fdictionary = fopen(dictionary, "r"); // THIS DICTIONARY IS THE ARGUMENT, NOT THE GLOBAL (WHICH YOU DON'T NEED)
- if (fdictionary == NULL)
- {
- fprintf(stderr, "Could not open %s.\n", dictionary);
- return 2;
- }
- // Allocate memory in the heap for the trie's first node, anchored by the root pointer
- node *root = malloc(sizeof(node)); // LOOK INTO CALLOC TO ZERO INITIALIZE THE WHOLE NODE
- if (root == NULL)
- {
- free(root);
- fprintf(stderr, "Could not malloc root\n");
- return 3;
- }
- // Set the traversal for building the trie at the root node
- node *trav = root;
- // Declare variables
- int gateLoad; // each character corresponds to a gate number
- // Begin constructing the trie
- for (int c = getc(fdictionary); c != EOF; c = fgetc(fdictionary)) // go through entire dictionary file
- {
- // if the character is part of a word
- if ( isalpha(c) || c == 39 )
- {
- // convert each character to a corresponding index number
- if (isalpha(c)) // if the character is alphabetical (guaranteed to be lowercase)
- {
- gateLoad = c - 97;
- }
- else if (c == 39) // if the character is an apostrophe
- {
- gateLoad = 26;
- }
- // map the character to the trie
- if (trav->children[gateLoad] == NULL) // if the character's gate has not been open
- {
- trav->children[gateLoad] = malloc(sizeof(node)); // create a new node
- *trav = *trav->children[gateLoad]; // move down the gate to the new node
- /*
- *******************************************************************************
- SAME AS BEFORE, WHY ARE YOU DEREFERENCING?
- ALSO VALID FOR THE ELSE RIGHT BELOW AND THE ELSE IF (C == 10) PART
- *******************************************************************************
- */
- }
- else // if the character's gate has already been open
- {
- *trav = *trav->children[gateLoad]; // move down the gate to the next node
- }
- }
- // if the character is a new break line indicating the end of a word
- else if (c == 10)
- {
- trav->is_word = true; // indicate the word is completed
- dict_wordCount++; // add one to the word counter
- *trav = *root; // move back to the beginning of the trie in preparation for loading the next word
- }
- }
- // close dictionary file
- fclose(fdictionary);
- // dictionary successfully loaded
- return true;
- }
- /**
- * Returns number of words in dictionary if loaded else 0 if not yet loaded.
- */
- unsigned int size(void)
- {
- bool dict_loaded = load(dictionary); // DO YOU REALLY WANT TO CALL THE LOAD FUNCTION AGAIN?
- // If the dictionary was successfully loaded
- if (dict_loaded == true)
- {
- // Return number of words loaded in the dictionary
- return dict_wordCount;
- }
- else
- // If the dictionary was not successfully loaded
- {
- // Return zero words loaded in the dictionary
- return 0;
- }
- }
- /**
- * Unloads dictionary from memory. Returns true if successful else false.
- */
- // unload calls freeNodes which is a function that takes in an argument for the ability to use recursion
- void freeNodes(node *eliminator)
- {
- // iterate over all gates in each node's children array
- for (int i = 0; i < 27; i++)
- {
- // starting at the root node, check all gates in current node
- if (eliminator->children[i] != NULL)
- {
- // travel down all opened gates in current node to following node
- freeNodes(eliminator->children[i]);
- }
- }
- // base case: free the root node pointer (when nothing else is dependent on it existing)
- free(eliminator);
- }
- bool unload(void)
- {
- // call freeNodes function, passing in root
- freeNodes(root);
- // indicate when the entire trie has been eliminated
- return true;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement