// Implements a dictionary's functionality
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include "dictionary.h"
// Represents number of buckets in a hash table
#define N 26
// Represents a node in a hash table
typedef struct node
{
char word[LENGTH + 1];
struct node *next;
}
node;
// Represents a hash table
node *hashtable[N];
//dictionary size
int dictionarysize = 0;
// Hashes word to a number between 0 and 25, inclusive, based on its first letter
unsigned int hash(const char *word)
{
return tolower(word[0]) - 'a';
}
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
// Initialize hash table
for (int i = 0; i < N; i++)
{
hashtable[i] = NULL;
}
// Open dictionary
FILE *file = fopen(dictionary, "r");
if (file == NULL)
{
unload();
return false;
}
// Buffer for a word
char word[LENGTH + 1];
// Insert words into hash table
while (fscanf(file, "%s", word) != EOF)
{
//Allocate space for new node
node *new_node = malloc(sizeof(node));
//If pointer returns NULL --> quit
if (new_node == NULL)
{
printf("could not malloc a new node\n");
unload();
return false;
}
dictionarysize ++;
//Add word into a new node
strcpy(new_node -> word, word);
//hash the words
int head = hash(word);
//If there is no node in the hashtable in the start
if (hashtable[head] == NULL)
{
hashtable[head] = new_node;
new_node -> next = NULL;
}
//Insert new node into node
else
{
new_node -> next = hashtable[head];
hashtable[head] = new_node;
}
}
// Close dictionary
fclose(file);
// Indicate success
return true;
}
// Returns number of words in dictionary if loaded, else 0 if not yet loaded
unsigned int size(void)
{
if (dictionarysize > 0)
{
return dictionarysize;
}
return 0;
}
// Returns true if word is in dictionary else false
bool check(const char *word)
{
//hash the words
int head = hash(word);
//place cursor on specific bucket
node *cursor = hashtable[head];
while (cursor != NULL)
{
//If string compared is 0, then found
if (strcasecmp(word, cursor -> word) == 0)
{
return true;
}
//If string is not found, go on to the next word
else
{
cursor = cursor -> next;
}
}
//Can't find the word -> mispelled word
return false;
}
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
for (int i = 0; i < N; i++)
{
//point to ith hashtable
node *cursor = hashtable[i];
while (cursor != NULL)
{
node *temp = cursor;
cursor = cursor -> next;
free(temp);
}
}
return false;
}
2 Answers
It looks like you haven't run the program to assess the result or at the very least didn't compare output with the supplied "key". Suggest you run it with any of the supplied texts. It will "fail". The bug is in unload
. From the spec:
Don’t move on until you’re sure you understand how speller itself works!
Odds are, you didn’t spend enough time looking over speller.c. Go back one square and walk yourself through it again!
-
hey, thanks for the reply. Could it be possible if you could elaborate on what you mean by comparing out with the supplied 'key'. I have ran the program. Commented Feb 3, 2020 at 0:48
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
for (int i = 0; i < N; i++)
{
//point to ith hashtable
node *cursor = hashtable[i];
while (cursor != NULL)
{
node *temp = cursor;
cursor = cursor -> next;
free(temp);
}
}
return false;
}
if anybody cares, its because i didn't change my last line in the unload function.
return false;
to
return true;
gg.