mirror of https://github.com/me50/kukemuna.git
This commit is contained in:
commit
78512bdd55
|
|
@ -0,0 +1,136 @@
|
|||
// Implements a dictionary's functionality
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
// Declares a dictionary's functionality
|
||||
|
||||
#ifndef DICTIONARY_H
|
||||
#define DICTIONARY_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
// 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
|
||||
Loading…
Reference in New Issue