From 78512bdd55979efe25f4609b99ec3daa8e242063 Mon Sep 17 00:00:00 2001 From: bot50 Date: Wed, 20 Mar 2024 21:13:01 +0000 Subject: [PATCH] kukemuna-cs50/problems/2024/x/speller@20240320T211301.881757995Z --- dictionary.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++ dictionary.h | 19 +++++++ 2 files changed, 155 insertions(+) create mode 100644 dictionary.c create mode 100644 dictionary.h diff --git a/dictionary.c b/dictionary.c new file mode 100644 index 0000000..23dc7d4 --- /dev/null +++ b/dictionary.c @@ -0,0 +1,136 @@ +// Implements a dictionary's functionality + +#include +#include +#include +#include +#include +#include + +#include "dictionary.h" + +// Represents a node in a hash table +typedef struct node +{ + char word[LENGTH + 1]; + struct node *next; +} node; + +// TODO: Choose number of buckets in hash table +const unsigned int N = 35536; + +// Hash table +node *table[N]; + +// counter for words +int wordcount = 0; + +// Returns true if word is in dictionary, else false +bool check(const char *word) +{ + // TODO + // +1 for NUL character + char lword[strlen(word) + 1]; + + for (int i = 0; i < strlen(lword); i++) + { + lword[i] = tolower((word[i])); + } + + // Set cursor to the head of approriate linked list + node *cursor = table[hash(lword)]; + + while (cursor != NULL) + { + if (strcasecmp(word, cursor->word) == 0) + { + return true; + } + cursor = cursor->next; + } + return false; +} + +// Hashes word to a number +unsigned int hash(const char *word) +{ + // TODO: Improve this hash function + // https://www.reddit.com/r/cs50/comments/1x6vc8/comment/cf9nlkn/ + 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 + // +1 for NUL character + char word[LENGTH + 1]; + + FILE *dict = fopen(dictionary, "r"); + if (dict == NULL) + { + return false; + } + + while (fscanf(dict, "%s", word) != EOF) + { + node *new_node = malloc(sizeof(node)); + + if (new_node == NULL) + { + unload(); + return false; + } + else + { + // Copy word to node + strcpy(new_node->word, word); + + // Get bucket index (linked list) + int n = hash(new_node->word); + + // Insert to list + new_node->next = table[n]; + table[n] = new_node; + wordcount++; + } + } + fclose(dict); + + return true; +} + +// Returns number of words in dictionary if loaded, else 0 if not yet loaded +unsigned int size(void) +{ + // TODO + if (wordcount > 0) + { + return wordcount; + } + return 0; +} + +// Unloads dictionary from memory, returning true if successful, else false +bool unload(void) +{ + // TODO + // For each hashtable bucket + for (int i = 0; i < N; i++) + { + node *cursor = table[i]; + + // For each linked list node + while (cursor != NULL) + { + node *tmp = cursor; + cursor = cursor->next; + free(tmp); + } + free(cursor); + } + return true; +} diff --git a/dictionary.h b/dictionary.h new file mode 100644 index 0000000..99e9904 --- /dev/null +++ b/dictionary.h @@ -0,0 +1,19 @@ +// Declares a dictionary's functionality + +#ifndef DICTIONARY_H +#define DICTIONARY_H + +#include + +// Maximum length for a word +// (e.g., pneumonoultramicroscopicsilicovolcanoconiosis) +#define LENGTH 45 + +// Prototypes +bool check(const char *word); +unsigned int hash(const char *word); +bool load(const char *dictionary); +unsigned int size(void); +bool unload(void); + +#endif // DICTIONARY_H