/*Implements a dictionary's functionality.*/
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include "dictionary.h"
// root node of trie, pointing to nothing
node* root = NULL;
// word counter, keep track of read words, set to zero
int word_count = 0;
/**
* Returns true if word is in dictionary else false.
*/
bool check(const char* word)
{
// iterate through word char-by-char
for (int index = 0, n = strlen(word); index < n; index++)
{
// conver each letter of word into lower case
char c = tolower(word[index]);
// to store index of children array
int i = 0;
if (c == '\'')
{
// is apostrophy (') detected, give it last index of the array
// i.e. size of array - 1
i = SIZE - 1;
}
else
{
// convert letter into 0-25 from a-z
i = c - 'a';
}
// create a tracker pointer to go through trie to check
node* tracker = root;
if (tracker->children[i] == NULL)
{
// ith letter of word is not poiting to anything
// means word is not in dictionary
return false;
}
else if (tracker->children[i] != NULL)
{
// poiting to something, so move to the next node
tracker = tracker->children[i];
}
// end of the word from text
if (index == n - 1)
{
return true;
}
}
return false;
}
/**
* Loads dictionary into memory. Returns true if successful else false.
*/
bool load(const char* dictionary)
{
// open dictionary in read only mode, sanity check
FILE* inptr = fopen(dictionary, "r");
if (inptr == NULL)
{
printf("Error! Couldn't open file.\n");
return false;
}
// give root node something to point to, do sanity check
root = malloc(sizeof(node));
if (root == NULL)
{
printf("Error! Out of Memory.\n");
fclose(inptr);
return false;
}
// to traverse through dictionary, tracker pointer poiting to root
node* tracker = root;
// read dictionary char-by-char to end of file
for (char c = fgetc(inptr); c != EOF; c = fgetc(inptr))
{
// set is_word flag to false
tracker->is_word = false;
// to store index of children array
int i = 0;
// to convert char into lowercase, make it easy to index
c = tolower(c);
// indexing
if (islower(c))
{
// if lower alpha, convert it into 0-25 from a-z
i = c - 'a';
}
else if (c == '\'')
{
// if char is apostrophe (') give it last index of the array
// i.e. size of array - 1
i = SIZE - 1;
}
else if (c == '\n')
{
// if char is \n, indicator of new word, flag is_word = true
tracker->is_word = true;
// update word counter
word_count++;
// reset tracker to root
tracker = root;
}
else
{
// if any of above char is not detected, error in word reading
i = -1;
break;
}
// end of the indexing
// use index to follow a path in trie
if (tracker->children[i] == NULL)
{
// tracker isn't pointing to anything
// create a new node to point to, do sanity check
node* new = malloc(sizeof(node));
if (new == NULL)
{
printf("Error! Out of Memory.\n");
fclose(inptr);
return false;
}
// make tracker to point to new node
tracker->children[i] = new;
// move tracker to point to next node
tracker = tracker->children[i];
}
else if (tracker->children[i] != NULL)
{
// pointer tracker is pointing to something
// move tracker to point to next node
tracker = tracker->children[i];
}
}
// close opened files
fclose(inptr);
// if everything goes fine
return true;
}
/**
* Returns number of words in dictionary if loaded else 0 if not yet loaded.
*/
unsigned int size(void)
{
// return number if word that are read
return word_count;
}
/**
* Unloads dictionary from memory. Returns true if successful else false.
*/
bool unload(void)
{
// TODO
return false;
}