-
-
Save coolnerdcool/f04eeafd64258b1e7cbd170470b6faae to your computer and use it in GitHub Desktop.
from CS50's PSET 5 speller
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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