Vince
Vince

Reputation: 136

Speller misspelled all words

All my words are misspelled when I run the program. It compiles but doesn't work as intended. I believe it has something to do with either the hash/check/or load function. I've checked it many times but can't figure out the problem. I've tried outputting the newWord variable to see if it returns a copy in all lower case but for some reason it doesn't print out. Maybe that means that all the values are NULL? So it might be a problem in my load function. I'll double check that again. Thanks in advance.

EDIT: Ran the debugger and I believe that the load function is returning correct values. I think it just has to be either my hash or check function.

#include <stdbool.h>
#include <strings.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "dictionary.h"

// Represents a node in a hash table
typedef struct node
{
    char word[LENGTH + 1];
    struct node *next;
}
node;

const unsigned int N = 17577;

// Hash table
node *table[N];

//words global variable
int words = 0;

// Returns true if word is in dictionary else false
bool check(const char *word)
{
    int hashValue = hash(word);
    if(hashValue == 17576){
        return false;
    }
    node *cursor = table[hashValue];
    printf("/%s", cursor->word);
    //review my notes for this while loop
    //basically tmp->next is pointing to the NEXT ITERATION
    //and tmp is our CURRENT ITERATION
    //so we want to check a value, if !true, continue
    while(cursor->next != NULL){
        if (strcasecmp(word, cursor->word) == 0){
            return true;
        }
        else{
            cursor = cursor->next;
        }
    }
    return false;
}


unsigned int hash(const char *word)
{
    const int ASCII_APOSTROPHE = 39;
    int alphaIndex;
    char *newWord = NULL;
    //make it lowercase for easier read
    for(int i = 0, n = strlen(word); i < n; i++){
        if(isalpha(word[i]) == 1){
            newWord[i] = tolower(word[i]);
        }
        else if(word[i] == ASCII_APOSTROPHE || isalpha(word[i]) == 2){
            newWord[i] = word[i];
        }
        else{
            //last index of array
            return 17576;
        }
    }
    
    if(strlen(newWord) >= 3){
        alphaIndex = (word[0] - 97) + (word[1] - 97) + (word[2] - 97);
    }
    else if(strlen(newWord) == 2){
         alphaIndex = (word[0] - 97) + (word[1] - 97);
    }
    else if(strlen(newWord) == 1){
        alphaIndex = (word[0] - 97);
    }
    else{
        alphaIndex = 0;
    }
    return alphaIndex;
}


// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    FILE *file = fopen(dictionary, "r");
    if(file == NULL){
        printf("Could not open file!\n");
        return false;
    }

  
   char *word = malloc(LENGTH + 1);

   while(fscanf(file, "%s", word) != EOF){
       node *n = malloc(sizeof(node));
       if(n == NULL){
           printf("Not enough memory!");
           return 1;
       }
       strcpy(n->word, word);
       n->next = table[hash(word)];
       table[hash(word)] = n;
       size();
   }
   free(word);
   fclose(file);
   return true;
}

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

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

Upvotes: 1

Views: 263

Answers (1)

Enis Arik
Enis Arik

Reputation: 677

There are two problems.

First one is that hash function is somehow running wrong. I did not debug it, I just replaced it with a very simple hash function (copied from https://stackoverflow.com/a/1469939/11000382).

unsigned int hash(const char *word)
{
    char c = word[0];
    int n = -1;
    static const char *const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    char *p = strchr(alphabet, toupper((unsigned char)c));

    if (p)
    {
        n = p - alphabet;
    }

    return n;
}

After this, I checked with $ ./speller texts/lalaland.txt but I was getting still more mispelled words (1738). However, it should be 955. Then I reviewed the check function, and I spotted a small bug.

This,

while(cursor->next != NULL){

Should be this,

while(cursor != NULL){

Then, it finds 955 mispelled words for lalaland.txt.

Upvotes: 1

Related Questions