From 2e089000eddeaa1236392be894bb538bfcee578b Mon Sep 17 00:00:00 2001 From: jfvillablanca <31008330+jfvillablanca@users.noreply.github.com> Date: Fri, 10 Nov 2023 06:48:18 +0800 Subject: [PATCH] sol: pset5/speller (unoptimized) --- pset5/speller/README.md | 1 + pset5/speller/dictionary.c | 135 +++++++++++++++++++++++++++++++++++++ pset5/speller/dictionary.h | 19 ++++++ 3 files changed, 155 insertions(+) create mode 100644 pset5/speller/README.md create mode 100644 pset5/speller/dictionary.c create mode 100644 pset5/speller/dictionary.h diff --git a/pset5/speller/README.md b/pset5/speller/README.md new file mode 100644 index 0000000..5ee2934 --- /dev/null +++ b/pset5/speller/README.md @@ -0,0 +1 @@ +https://cs50.harvard.edu/x/2023/psets/5/speller/ diff --git a/pset5/speller/dictionary.c b/pset5/speller/dictionary.c new file mode 100644 index 0000000..2135d3f --- /dev/null +++ b/pset5/speller/dictionary.c @@ -0,0 +1,135 @@ +// Implements a dictionary's functionality + +#include +#include +#include +#include +#include +#include + +#include "dictionary.h" + +// Dictionary file +FILE *dictionary_file = NULL; +int word_count = 0; + +// 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 = 26; + +// Hash table +node *table[N]; + +// FUNCTION PROTOTYPES +void free_linked_list(node *head); + +// Returns true if word is in dictionary, else false +bool check(const char *word) +{ + int hash_index = hash(word); + + node *current_node = table[hash_index]; + while (current_node != NULL) + { + if (strcasecmp(word, current_node->word) == 0) + { + return true; + } + current_node = current_node->next; + } + + return false; +} + +// Hashes word to a number +// The function used here is a *polynomial rolling hash function* +// Reference: https://cp-algorithms.com/string/string-hashing.html +unsigned int hash(const char *word) +{ + // TODO: Improve this hash function + return toupper(word[0]) - 'A'; +} + +// Loads dictionary into memory, returning true if successful, else false +bool load(const char *dictionary) +{ + dictionary_file = fopen(dictionary, "r"); + + char word_buffer[LENGTH + 1]; + if (dictionary_file != NULL) + { + while (fscanf(dictionary_file, "%s", word_buffer) == 1) + { + node *new_node = calloc(1, sizeof(node)); + word_count++; + + // Set the next of a new_node to NULL by default + // new_node->next = NULL; + + if (new_node != NULL) + { + strcpy(new_node->word, word_buffer); + int hash_index = hash(new_node->word); + + // First instance to the specific index + if (table[hash_index] == NULL) + { + table[hash_index] = new_node; + // printf("first head: %s\n", new_node->word); + } + else + { + // Point new_node to the current head at index + new_node->next = table[hash_index]; + // Then point the head to the new node + table[hash_index] = new_node; + // printf("new head: %s | old head: %s\n", table[hash_index]->word, table[hash_index]->next->word); + } + } + } + return true; + } + + return false; +} + +// Returns number of words in dictionary if loaded, else 0 if not yet loaded +unsigned int size(void) +{ + return word_count; +} + +// Unloads dictionary from memory, returning true if successful, else false +bool unload(void) +{ + for (int i = 0; i < N; i++) + { + if (table[i] != NULL) + { + free_linked_list(table[i]); + } + } + + if (fclose(dictionary_file) == 0) + { + return true; + } + return false; +} + +void free_linked_list(node *head) +{ + node *tmp; + while (head != NULL) + { + tmp = head; + head = head->next; + free(tmp); + } +} diff --git a/pset5/speller/dictionary.h b/pset5/speller/dictionary.h new file mode 100644 index 0000000..99e9904 --- /dev/null +++ b/pset5/speller/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