1

I have implemented everything else but this check function when I try to test it it seems like the the check function isn't working, because the no. of misspelled words is the same as the no. in text.. I check the logic of my code and it seems right to me... I first make them lowercase then use the hash function on them and then check if the word is in the hash table.

// Returns true if word is in dictionary else false
bool check(const char *word)
{
    // TODO
    int len = strlen(word);
    char copy[len + 1];

    for (int i = 0; i != '\0'; i++)
    {
        copy[i] = tolower(word[i]);
    }

    int index = hash(copy);

    node *tmp = table[index];

    while (tmp != NULL)
    {
        if (strcmp(tmp->word, copy) == 0)
        {
            return true;
        }

        tmp = tmp->next;
    }

    return false;
}

Here's my hash function and load function..

// Hashes word to a number
unsigned int hash(const char *word)
{
    /* credits to...
     *https://www.reddit.com/r/cs50/comments/1x6vc8/pset6_trie_vs_hashtable/
     */
    unsigned int hash = 0;
    for (int i = 0, n = strlen(word); i < n; i++)
    {
        hash = (hash << 2) ^ word[i];
    }
    return hash % N;
}

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    // TODO
    char *words = malloc(sizeof(char) * (LENGTH + 1));
    if (words == NULL)
    {
        return 1;
    }
    // initialize the hash table to NULL
    for (int i = 0; i < N; i++)
    {
        table[i] = NULL;
    }

    // open dictionary file
    FILE *indata = fopen(dictionary, "r");


    // 1 character for '\0' and another for '\n' because fgets takes a trailing new line
    // when it reads 'man' the value of words will be "man\n\0" so meaning 2 extra characters
    while (fgets(words, LENGTH + 2, indata) != NULL)
    {
        // get the index by using the hash function
        int index = hash(words);
        // allocate memory for the newNode
        node *newNode = malloc(sizeof(node));
        if (newNode == NULL)
        {
            return false;
        }

        // get rid of the trailing new line from fgets
        words[strlen(words) - 1] = '\0';
        strcpy(newNode->word, words);
        // make the newNode the head of the list
        newNode->next = table[index];
        table[index] = newNode;

    }

    // free memory and close the opened file
    free(words);
    fclose(indata);
    return true;
}

1 Answer 1

0

This is broken:

for (int i = 0; i != '\0'; i++)
{
    copy[i] = tolower(word[i]);
}

Think about it. The for loop is supposed to go through all the chars in the string word. The problem is that the limit isn't going to work like you expect. The limit is based on '\0'. It should be based on the length of the string word, i.e., on len. Perhaps you thought you were looking for the end of string marker. Then, you'd want to look for word[i] == '\0'

The bottom line is that the result is unpredictable, and you're probably getting a bad hash.

Or, if you were fortunate enough that it worked, then there may be an issue in load.

1
  • I changed it already into word[i] != NULL and it didn't make a difference, i also tried i < len and it also didn't make a difference. I've edited my question and added m hash and load functions for reference
    – Ojou Nii
    Apr 17, 2020 at 10:33

You must log in to answer this question.

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