forked from Federico-abss/CS50-intro-course
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dictionary.c
130 lines (109 loc) · 2.89 KB
/
dictionary.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Implements a dictionary's functionality
#include <stdbool.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <strings.h>
#include <stdio.h>
#include "dictionary.h"
// Represents a node in a hash table
typedef struct node
{
char word[LENGTH];
struct node *next;
}
node;
// Number of buckets in hash table
const unsigned int N = 26;
// Hash table
node *table[N];
int totalWords = 0;
// Returns true if word is in dictionary else false
bool check(const char *word)
{
node *cursor = table[hash(word)];
//compare words case insensitive
if (strcasecmp(cursor->word, word) == 0)
{
return true;
}
//keep traversing linked list until it finds the word or it finishes
while (cursor->next != NULL)
{
cursor = cursor->next;
if (strcasecmp(cursor->word, word) == 0)
{
return true;
}
}
return false;
}
// Hashes word to a number
// simply used one bucket for every letter, a = 0, b = 1 ... z = 25
unsigned int hash(const char *word)
{
int n = (int) tolower(word[0]) - 97;
return n;
}
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
// opens the dictionary and initializes temporary space to hold the words
FILE *file = fopen(dictionary, "r");
char *dictWord = malloc(LENGTH);
if (dictWord == NULL)
{
return false;
}
// reads file until the end
while (fscanf(file, "%s", dictWord) != EOF)
{
// allocates memory for a node in which the word will be inserted
node *n = malloc(sizeof(node));
if (n == NULL)
{
return false;
}
// copies the word in the chunk of memory allocated and then updates the words count
strcpy(n->word, dictWord);
totalWords++;
// set next to point at beginning of list
n->next = table[hash(dictWord)];
// set array to point at n which becomes new beginning of the list
table[hash(dictWord)] = n;
}
fclose(file);
free(dictWord);
return true;
}
// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
return totalWords;
}
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
// creates two pointers to traverse the linked list and cancel its element without losing its address
node *tmp;
node *cursor;
// repeats for every index in the table
for (int i = 0; i < N; i++)
{
if (table[i] == NULL)
{
continue;
}
cursor = table[i];
tmp = cursor;
// until the end of the list keeps freeing the memory allocated in load
while (cursor->next != NULL)
{
cursor = cursor->next;
free(tmp);
tmp = cursor;
}
free(cursor);
}
return true;
}