0
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cs50.h>
#include <strings.h>

#include "dictionary.h"

#define N 26

typedef struct node
{
    char word[LENGTH + 1];
    struct node *next;
}
node;

// Represents a hash table
node *hashtable[N];

// 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';
}

// Keeps track of number of words
int word_count = 0;

int loaded = 1;

// 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];

    for (int i = 0; i < N; i++)
    {
        while ((fscanf(file, "%s", word) != EOF) &&
        (hash(word) == i))
        {
            // Creates a new node
            node *new_node = malloc(sizeof(node));
            if (new_node == NULL)
            {
                unload();
                return false;
            }

            // Copies the word into the word portion of the node, increments number of words
            strcpy(new_node->word, word);
            word_count++;
        }
    }

    fclose(file);
    loaded = 0;
    return true;
}

// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
    return word_count;
}

// Returns true if word is in dictionary else false
bool check(const char *word)
{
    unsigned int i = hash(word);

    // Go to part of dictionary with the same starting letter
    node *cursor = hashtable[i];
    while (cursor != NULL)
    {
        if (strcasecmp(word, cursor->word) == 0)
        {
            return true;
        }

        cursor = cursor->next;
    }

    return false;
}

// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
    for (int i = 0; i < N; i++)
    {
        node *cursor = hashtable[i];
        while (cursor != NULL)
        {
            node *temp = cursor;
            cursor = cursor->next;
            free(temp);
        }
    }

    return true;
}

The first word of every letter other than a doesn't load in from the large dictionary (a loads in, but not baa, etc.)...and every word is misspelled. Why is this?

0

To be accurate, it looks like no words are being loaded into the tree. There is no code in load that adds a node to hashtable[]. All nodes that are being created are immediately lost.

Assuming that the code to do so did exist, there's another issue. I don't understand the purpose of the for loop at all. It causes only words that begin with "a" to be processed. Here's how that happens. The for loop will require only words that start with a to be processed on the first pass through the loop. The while loop will run through the dictionary file in that first for loop pass. On the second for loop pass, the dictionary file has been exhausted and nothing else will be processed.

This code needs a substantial amount of work. Too much code is missing and some of the existing code is detrimental.

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

4
  • are there any issues with the check and unload functions?
    – Sean Cheng
    Apr 13 '19 at 22:45
  • Well, that would be for you to find first, wouldn't it? ;-)
    – Cliff B
    Apr 13 '19 at 23:54
  • Is the number of buckets correct? I don't know how to implement it with one bucket for each letter.
    – Sean Cheng
    Apr 14 '19 at 2:29
  • Ummm.... you already did.
    – Cliff B
    Apr 14 '19 at 21:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .