Skip to content

Instantly share code, notes, and snippets.

@coolnerdcool
Last active October 22, 2018 17:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save coolnerdcool/f04eeafd64258b1e7cbd170470b6faae to your computer and use it in GitHub Desktop.
Save coolnerdcool/f04eeafd64258b1e7cbd170470b6faae to your computer and use it in GitHub Desktop.
from CS50's PSET 5 speller
/**
* Implements a dictionary's functionality.
*
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include "dictionary.h"
unsigned int hasher(const char *word);
typedef struct node
{
char val[LENGTH + 1];
struct node *next;
} Node;
Node *hashTable[HASH_MAX];
Node *headNode = NULL;
unsigned int numberOfWords = 0; // For size()
// hash funtion
unsigned int hasher(const char* word)
{
unsigned long hash = 5381;
for (const char* ptr = word; *ptr != '\0'; ptr++)
{
hash = ((hash << 5) + hash) + tolower(*ptr);
}
return hash % HASH_MAX;
}
/**
* Returns true if word is in dictionary else false.
*/
bool check(const char *word)
{
Node *cursor;
int hashed;
int i = 0;
int comparison; // only if the value is 0 means that both words match
char lowercased_word[LENGTH+1]; // using to store every word in lowercase
// Checking that THERE IS a word to compare with.
if (word == NULL)
{
printf("Empty file. Maybe try with another file.\n");
return false;
}
// iterate over the word & convert to lower-case
for (i = 0; word[i]; i++)
{
lowercased_word[i] = tolower(word[i]);
}
lowercased_word[i] = '\0';
// copy the lowercased word to the node
hashed = hasher(lowercased_word); // get the position in the hashtable
cursor = hashTable[hashed];
// iterate over the hashtable and check inside it
while (cursor != NULL) // iterate over all the hashTable
{
comparison = strcmp(cursor -> val, lowercased_word); // compare the argument word with the word in turn from the dictionary.
if(comparison == 0) {
return true;
}
else
{
cursor = cursor -> next;
}
}
return false;
}
/* --- --- ---*/
/**
* Loads dictionary into memory. Returns true if successful else false.
* Dictionary contains valid words, one per line.
*/
bool loadWord(char *word)
{
int hashed;
Node *a_new_node;
a_new_node = malloc(sizeof(Node));
hashed = hasher(word); // this one gives the position inside the hashtable
strcpy(a_new_node -> val, word);
// move elements and add it to the beginning
a_new_node -> next = hashTable[hashed];
hashTable[hashed] = a_new_node;
return true;
}
bool load(const char *dictionary)
{
// load function receives a string that presents a dictionary file from main.
FILE *fp = fopen(dictionary, "r"); // load uses fopen to open the dictionary file for loading.
char word[LENGTH + 1];
// load checks if the value was successfully opened
if (fp == NULL)
{
// if not load returns false
return false;
}
// else read every word in the dictionary
while (fscanf(fp, "%s", word) != EOF)
{
loadWord(word);
numberOfWords++;
}
return true;
}
/**
* Returns number of words in dictionary if loaded else 0 if not yet loaded.
*/
unsigned int size(void)
{
return numberOfWords;
}
/**
* Unloads dictionary from memory. Returns true if successful else false.
*/
bool unload(void)
{
Node *cursor;
cursor = hashTable[HASH_MAX - 1];
// hashed = hasher();
// cursor = hashTable[hashed]; // what does this do? is it needed?
while (cursor != NULL)
{
Node *temp = cursor;
cursor = cursor -> next;
free(temp);
}
free(cursor);
return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment