I used hash table to store dictionary in pset5. In order to minimize run time, I chose to cite a hash function online instead of writing my own hash table of maybe 26 rows for 26 letters. I wrote the load, check, and size function. Haven't started unload yet. But when I tried the large dictionary and a short text, it seems the dictionary is loaded successfully (not quite sure), but nothing is checked. All words are listed in the terminal window. Global variables are int word_counter (used to count words in the dictionary loaded) and struct node.
#define DICTIONARY_SIZE 143091
typedef struct node
{
char word[LENGTH+1];
struct node* next;
}
node;
//prototype
int word_counter;
node* hashtable[DICTIONARY_SIZE];
int hash (const char* word);
/**
* Returns true if word is in dictionary else false.
*/
bool check(const char* word)
{
char lower_word[LENGTH+1];
for (int i = 0, i < LENGTH+1; i++)
lower_word[i] = 0;
//decapatalize words in text
for (int i = 0, n = strlen(word); i < n; i++)
{
if (isupper (word[i]))
{
lower_word[i] = tolower(word[i]);
}
else
{
lower_word[i] = word[i];
}
}
int hashcode = hash(lower_word);
node* traversal = hashtable[hashcode];
while (traversal != NULL)
{
if (strcmp(lower_word, traversal->word) == 0)
{
return true;
}
else
{
traversal = traversal->next;
}
}
free(traversal);
return false;
}
/**
* Loads dictionary into memory. Returns true if successful else false.
*/
bool load(const char* dictionary)
{
//open dictionary file
FILE* in_file = fopen(dictionary, "r");
//check if the file can be open
if (in_file == NULL)
{
printf("cannot open dictionary file\n");
return 1;
}
word_counter = 0;
char new_word[LENGTH+1];
for(int i = 0; i < LENGTH+1; i++)
new_word[i] = 0;
while (fscanf(in_file, "%s", new_word) == 1)
{
node* new_node = malloc(sizeof(node));
strcpy(new_node->word, new_word);
int hashcode = hash(new_node->word);
if (hashtable[hashcode] == NULL)
{
hashtable[hashcode] = new_node;
new_node->next = NULL;
word_counter++;
}
else
{
new_node->next = hashtable[hashcode];
hashtable[hashcode] = new_node;
word_counter++;
}
}
free(new_node);
fclose(in_file);
return true;
}
/**
* Returns number of words in dictionary if loaded else 0 if not yet loaded.
*/
unsigned int size(void)
{
return word_counter;
}
bool unload(void)
{
for (int i = 0; i < DICTIONARY_SIZE; i++)
{
node* cursor = hashtable[i];
while (cursor != NULL);
{
node* tmp = cursor;
cursor = cursor->next;
free(tmp);
}
free(cursor);
}
return true;
}
//hash function from http://stackoverflow.com/questions/20462826/hash-function-for-strings-in-c
int hash (const char* word)
{
int hash = 0;
int n;
for (int i = 0; word[i] != '\0'; i++)
{
// alphabet case
if(isalpha(word[i]) || word[i] == '\'')
{
n = word[i] - 'a' + 1;
}
//apostrophe case
else
{
n = 27;
}
hash = ((hash << 3) + n) % DICTIONARY_SIZE;
}
return hash;
}