Created
July 6, 2020 06:50
-
-
Save suhitaga/a086bb7060ca303bf63dbc6f8df54b8a to your computer and use it in GitHub Desktop.
This file contains hidden or 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 <ctype.h> | |
#include <stdbool.h> | |
#include <strings.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include "dictionary.h" | |
// Represents a node in a hash table | |
typedef struct node | |
{ | |
char word[LENGTH + 1]; | |
struct node *next; | |
} | |
node; | |
// Number of buckets in hash table | |
const unsigned int N = 17602; | |
// Number of words in dictionary | |
long word_count = 0; | |
// Hash table | |
node *table[N]; | |
// Keeps track of whether the hashtable is filled or not | |
bool is_table_filled = false; | |
// Returns true if word is in dictionary else false | |
bool check(const char *word) | |
{ | |
//hashing the word | |
int index = hash(word); | |
//traversing the linked list at the particular index | |
if (table[index] != NULL) | |
{ | |
for (node *nptr = table[index]; nptr != NULL; nptr = nptr->next) | |
{ | |
if (strcasecmp(nptr->word, word) == 0) | |
{ | |
return true; | |
} | |
} | |
} | |
return false; | |
} | |
// Hashes word to a number | |
unsigned int hash(const char *word) | |
{ | |
//Implemented a hash table which contains a,b,c,d,...,x,y,z,aaa,aab,...,zzx,zzy,zzz | |
//all words that are less than 6 letters long, are placed in the first part of table | |
//all words greater than 5 words are placed in the second part of the table | |
//you might argue that most of the stuff in the second part is not even present in the Eng. language | |
//but my aim is to reduce time not size and I believe that this hash function achieves that | |
int l = strlen(word), index = 0; | |
if (l < 6) | |
{ | |
char c = tolower(word[0]); | |
index = (int)c - 97; | |
return index; | |
} | |
else | |
{ | |
char c[3]; | |
for (int i = 0; i < 3; i++) | |
{ | |
c[i] = tolower(word[i]); | |
} | |
index = 26 + (((int)c[0] - 97) * 676) + (((int)c[1] - 97) * 26) + ((int)c[0] - 97); | |
return index; | |
} | |
return 0; | |
} | |
// Loads dictionary into memory, returning true if successful else false | |
bool load(const char *dictionary) | |
{ | |
//Open dictionary file | |
FILE *input = fopen(dictionary, "r"); | |
if (input == NULL) | |
{ | |
fprintf(stderr, "Could not open %s.\n", dictionary); | |
return false; | |
} | |
char buffer[LENGTH]; | |
//Read strings from file one at a time | |
while (fscanf(input, "%s", buffer) != EOF) | |
{ | |
//memory allocation | |
node *n = malloc(sizeof(node)); | |
if (n == NULL) | |
{ | |
//free the rest of the memory to prevent segfault | |
unload(); | |
fprintf(stderr, "Out of memory!\n"); | |
return false; | |
} | |
//copying the current word in the dictionary to | |
strcpy(n->word, buffer); | |
//procuring the hash index for the new word read from the dictionary | |
int index = hash(buffer); | |
//insertion into the hashtable | |
n->next = table[index]; | |
table[index] = n; | |
//for the size | |
word_count++; | |
} | |
fclose(input); | |
is_table_filled = true; | |
return true; | |
} | |
// Returns number of words in dictionary if loaded else 0 if not yet loaded | |
unsigned int size(void) | |
{ | |
if (!is_table_filled) | |
{ | |
return 0; | |
} | |
return word_count; | |
} | |
// Unloads dictionary from memory, returning true if successful else false | |
bool unload(void) | |
{ | |
if (!is_table_filled) | |
{ | |
return false; | |
} | |
for (int i = 0; i < N; i++) | |
{ | |
if (table[i] != NULL) | |
{ | |
for (node *nptr = table[i]; nptr != NULL;) | |
{ | |
node *temp = nptr; | |
nptr = nptr->next; | |
free(temp); | |
} | |
} | |
} | |
return true; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment