Reputation: 136
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
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