Created
July 10, 2021 20:10
-
-
Save e200/c2dac25874206ac30e8e79ff75444fbf to your computer and use it in GitHub Desktop.
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 <stdbool.h> | |
#include <string.h> | |
#include <strings.h> | |
#include <stdlib.h> | |
#include <stdio.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; | |
int dictionaryLength = 0; | |
int asciiIndexForACharacter = 97; | |
node *createNode(char *word); | |
void attachNode(node *parentNode, node *childNode); | |
void freeNodes(node *firstNode); | |
bool wordExistsInAnyNode(const char *word, node *firstNode); | |
int charIndex(char character); | |
// Number of buckets in hash table | |
// 25^2 + 1 = 626 -> a, b, c, aa, bb, cc | |
// Last one is to store non-alpha chars | |
const unsigned int N = 625; | |
// Hash table | |
node *table[N]; | |
// Returns true if word is in dictionary, else false | |
bool check(const char *word) | |
{ | |
int tableIndex = hash(word); | |
return wordExistsInAnyNode(word, table[tableIndex]); | |
} | |
// Hashes word to a number | |
unsigned int hash(const char *word) | |
{ | |
char c0 = word[0]; | |
if (strlen(word) > 1) | |
{ | |
char c1 = word[1]; | |
if (isalpha(c0) && isalpha(c1)) | |
{ | |
return charIndex(c0) + charIndex(c1); | |
} | |
else | |
{ | |
return N - 1; | |
} | |
} | |
else | |
{ | |
if (isalpha(c0)) | |
{ | |
return charIndex(c0); | |
} | |
else | |
{ | |
return N - 1; | |
} | |
} | |
} | |
// Loads dictionary into memory, returning true if successful, else false | |
bool load(const char *dictionary) | |
{ | |
// TODO | |
FILE *fptr = fopen(dictionary, "r"); | |
if (fptr == NULL) | |
{ | |
printf("Unable to read the given file. Reason: file doesn\'t exists or is unreadable.\n"); | |
fclose(fptr); | |
return false; | |
} | |
char word[LENGTH + 1]; | |
while (fscanf(fptr, "%s", word) != EOF) | |
{ | |
int wordHash = hash(word); | |
node *n = createNode(word); | |
if (table[wordHash] == NULL) | |
{ | |
table[wordHash] = n; | |
} | |
else | |
{ | |
attachNode(table[wordHash], n); | |
} | |
dictionaryLength++; | |
} | |
fclose(fptr); | |
return true; | |
} | |
// Returns number of words in dictionary if loaded, else 0 if not yet loaded | |
unsigned int size(void) | |
{ | |
return dictionaryLength; | |
} | |
// Unloads dictionary from memory, returning true if successful, else false | |
bool unload(void) | |
{ | |
for (int i = 0; i < N; i++) | |
{ | |
node *currentNode = table[i]; | |
if (currentNode != NULL) | |
{ | |
freeNodes(currentNode); | |
} | |
} | |
return true; | |
} | |
node *createNode(char *word) | |
{ | |
node *n = malloc(sizeof(node)); | |
if (n == NULL) | |
{ | |
exit(1); | |
} | |
strcpy(n->word, word); | |
n->next = NULL; | |
return n; | |
} | |
void attachNode(node *parentNode, node *childNode) | |
{ | |
if (parentNode->next == NULL) | |
{ | |
parentNode->next = childNode; | |
} | |
else | |
{ | |
attachNode(parentNode->next, childNode); | |
} | |
} | |
void freeNodes(node *nodeToRelease) | |
{ | |
if (nodeToRelease == NULL) | |
{ | |
return; | |
} | |
if (nodeToRelease->next != NULL) | |
{ | |
freeNodes(nodeToRelease->next); | |
} | |
free(nodeToRelease); | |
} | |
bool wordExistsInAnyNode(const char *word, node *firstNode) | |
{ | |
if (strcasecmp(firstNode->word, word) == 0) | |
{ | |
return true; | |
} | |
else if (firstNode->next != NULL) | |
{ | |
return wordExistsInAnyNode(word, firstNode->next); | |
} | |
return false; | |
} | |
int charIndex(char character) | |
{ | |
return tolower(character) - asciiIndexForACharacter; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment