forked from benbrandt/cs50
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdictionary.c
172 lines (145 loc) · 3.34 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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/**
* dictionary.c
*
* Computer Science 50
* Problem Set 5
*
* Implements a dictionary's functionality.
*/
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "dictionary.h"
// Node Definition
typedef struct node
{
bool is_word;
struct node* children[27];
}
node;
// Root Node
node* root;
// Size of trie
unsigned int total_nodes = 0;
/**
* Returns index of letter within trie array
*/
int getIndex(const char c)
{
if (c == '\'')
{
return 26;
}
else
{
return tolower(c) % 'a';
}
}
/**
* Returns true if word is in dictionary else false.
*/
bool check(const char* word)
{
// Set cursor to root
node* cursor = root;
// for each letter in input word
for (int i = 0; word[i] != '\0'; i++)
{
// Find the index of the letter
int index = getIndex(word[i]);
// got to corresponding element in children
if (cursor->children[index] == NULL)
{
// if NULL word is mispelled
return false;
}
// if not NULL, move to next letter
cursor = cursor->children[index];
}
// once at end of input word, check if is_word is true
return cursor->is_word;
}
/**
* Loads dictionary into memory. Returns true if successful else false.
*/
bool load(const char* dictionary)
{
// Create space for root
root = malloc(sizeof(node));
// Initialize number of nodes
total_nodes = 0;
// Read dictionary
FILE* fp = fopen(dictionary, "r");
if (fp == NULL)
{
printf("Could not open %s.\n", dictionary);
unload();
return false;
}
// Set cursor to root
node* cursor = root;
// Read each character in dictionary
for (int c = fgetc(fp); c != EOF; c = fgetc(fp))
{
// Check if newline
if (c == '\n')
{
// mark as word
cursor->is_word = true;
// Increment number of nodes
total_nodes++;
// reset cursor to root to traverse trie again
cursor = root;
}
else
{
// Find the index of the letter
int index = getIndex(c);
// Check if node exists for letter
if (cursor->children[index] == NULL)
{
// Create new node
cursor->children[index] = malloc(sizeof(node));
}
// Move to next node
cursor = cursor->children[index];
}
}
// Close dictionary
fclose(fp);
return true;
}
/**
* Returns number of words in dictionary if loaded else 0 if not yet loaded.
*/
unsigned int size(void)
{
return total_nodes;
}
/**
* Check node children to see if they can be freed
*/
bool free_nodes(node* ptr)
{
// Go through node's children
for (int i = 0; i < 27; i++)
{
// If child is pointer, recursively check that one as well
if (ptr->children[i] != NULL)
{
free_nodes(ptr->children[i]);
}
}
// If all chilren are null, free node
free(ptr);
return true;
}
/**
* Unloads dictionary from memory. Returns true if successful else false.
*/
bool unload(void)
{
// Start at root
return free_nodes(root);
}