0

Whenever i run the program it always displays number of words in dictionary as 26. When i try to debug using debug50 loading looks fine but when i debug the size part it display 0x0 against the next pointer for the first word in the dictionary for each alphabet. Cannot find the bug even after trying for hours, any help is appreciated.

#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "dictionary.h"

#define N 26

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

node *hashtable[N];

unsigned int hash(const char *word)
{
    return tolower(word[0]) - 'a';
}

bool load(const char *dictionary)
{
    for (int i = 0; i < N; i++)
    {
        hashtable[i] = NULL;
    }

    FILE *file = fopen(dictionary, "r");
    if (file == NULL)
    {
        unload();
        return false;
    }

    char word[LENGTH + 1];

    while (fscanf(file, "%s", word) != EOF)
    {
        unsigned int bucket = hash(word);

        node *tmp = malloc(sizeof(node));
        if(!tmp)
        {
            unload();
            return false;
        }

        strcpy(tmp->word, word);
        tmp->next = NULL;

        if (hashtable[bucket])
        {
            node *ptr = hashtable[bucket];
            while (ptr)
            {
                ptr = ptr->next;
            }

            ptr = tmp;
        }
        else
        {
            hashtable[bucket] = tmp;
        }
    }

    fclose(file);

    return true;
}

unsigned int size(void)
{
    unsigned int n = 0;

    for (int bucket = 0; bucket < N; bucket++)
    {
        for (node *ptr = hashtable[bucket]; ptr != NULL; ptr = ptr->next)
        {
            n++;
        }
    }

    return n;
}

bool check(const char *word)
{
    unsigned int bucket = hash(word);
    char word_lc[LENGTH + 1];

    int n = strlen(word);
    for (int i = 0; i < n; i++)
    {
        word_lc[i] = tolower(word[i]);
    }
    word_lc[n] = '\0';

    for (node *tmp = hashtable[bucket]; tmp != NULL; tmp = tmp->next)
    {
        if (!(strcmp(tmp->word, word_lc)))
        {
            return true;
        }
    }

    return false;
}

bool unload(void)
{
    for (int bucket = 0; bucket < N; bucket++)
    {
        node *ptr = hashtable[bucket];

        while (ptr)
        {
            node *tmp = ptr;
            ptr = ptr->next;
            free(tmp);
        }
    }

    return true;
}

1 Answer 1

0

Let's look at this.

        while (ptr)
        {
            ptr = ptr->next;
        }

        ptr = tmp;

ptr walks to the end of the linked list. Eventually, it gets to ptr->next that is set to null. It then assigns that null to ptr and ends the loop. Next, ptr is assigned to tmp. Unfortunately, that doesn't add anything to the end of the list. That last ptr->next would need to have been set to tmp, not ptr to tmp.

This also explains why only 26 words. Only the first node on each linked list exists - the node residing in the hashtable. It's impossible to add a second word to any list.

It would be a good exercise to get this working, but after you do, think about this. Adding to the end of an unsorted list is inefficient. Have you thought about inserting the new node to the beginning of the list?

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

You must log in to answer this question.