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