0

I realize that many people have asked this question before but I didn't find my answer in any of them. Or maybe I'm just too stupid to see it. Anyways my code seems to work except that all the words are considered misspelled. I think it might be because of check function but I'm not sure how to fix it. please help me figure it out. Thanks!

// Implements a dictionary's functionality

#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <string.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];

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

//initialize words counter & head pointer
int count = 0;
node *head;

// 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)
    {
        /// TODO ///


        //hash the word
        int k = hash(word);
        //store address of node into head
        head = hashtable[k];


        //allocate space for a node
        hashtable[k] = (node*)malloc(sizeof(node));

        //verify that we have space to allocate for that node
        if (hashtable[k] == NULL)
        {
            printf("not enough space in memory\n");
            unload();
            return false;
        }

        //copy word into node
        strcpy(hashtable[k]->word, word);

        if (head == NULL)
        {
            //make that node point to NULL
            hashtable[k]->next = NULL;

            //intcrement words counter
            count++;
        }
        else
        {
            //link new node to the old head
            hashtable[k]->next = head;

            //make the new node head of the linked list
            head = hashtable[k];

            //intcrement words counter
            count++;

        }

    }

    // 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)
{
    /// TODO ///


    return count;
}

// Returns true if word is in dictionary else false
bool check(const char *word)
{
    /// TODO ///


    int k = hash(word);
    node *cur = hashtable[k];

    //go through node and search for word
    while (cur != NULL)
    {
        //compare word in text with word in dictionary
        if (strcasecmp(hashtable[k]->word, word) == 0)
        {
            return true;
        }

        cur = cur->next;
    }

    return false;
}

// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
    /// TODO ///


    //initialize cur to head
    node *cur = head;
    //loop through nodes until hitting NULL
    while (cur != NULL)
    {
        //store cur into temp
        node *temp = cur;
        //make cur point to next node
        cur = cur->next;
        //free node pointed to by temp
        free(temp);
    }

    return true;
    //return false;
}
1

Interesting. I ran a test using a small dictionary and noted immediately that the only words that were coming back as correct were the ones pointed to by the pointers in hashtable. Anything that wasn't the first node in a linked list was misspelled. This is as often a problem with load() as it is with check(), but let's look at the heart of check() first.

    while (cur != NULL)
    {
        //compare word in text with word in dictionary
        if (strcasecmp(hashtable[k]->word, word) == 0)
        {
            return true;
        }
        cur = cur->next;
    }

This code sets cur to point at the first node in the linked list, hashtable[k]. It then checks whether hashtable[k]->word matches the word being checked. If not, it then moves cur to point to the next node and restarts the loop.

Unfortunately, it isn't checking the word in node cur, it's RECHECKING hashtable[k]->word, over and over, until cur reaches the end of the linked list.

The code is checking the wrong thing.

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

| improve this answer | |
  • Sorry I'm not sure how to fix it can you be more explicit please ? – John Doe Apr 9 '19 at 10:02
  • it's NOT checking cur->word, it's checking hashtable[k]->word each time. – Cliff B Apr 9 '19 at 10:12
  • I have tried using cur->word instead but it just makes all words correct even when they are not on the dictionary. – John Doe Apr 9 '19 at 20:45
  • I think that using cur->word is just checking the same word since both cur->word and hashtable->word are pointing to the same thing. I'm not sure what to so here. – John Doe Apr 9 '19 at 22:36
  • cur->word is only the same as hashtable->word on the first pass through the loop. cur = cur->next; changes cur to point at the next node in the linked list. – Cliff B Apr 10 '19 at 0:40
0

I think I got it. I was using my own text file so I didn't notice that the latter should end with /n in order to check all words. Thanks for your help.

| improve this answer | |

You must log in to answer this question.

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