-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtrie.c
155 lines (129 loc) · 3.2 KB
/
trie.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
// Saves popular dog names in a trie
// https://www.dailypaws.com/dogs-puppies/dog-names/common-dog-names
#include <cs50.h>
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE_OF_ALPHABET 26
#define MAXCHAR 20
typedef struct node
{
bool is_word;
struct node *children[SIZE_OF_ALPHABET];
} node;
// Function prototypes
bool check(char *word);
bool unload(void);
void unloader(node *current);
// Root of trie
node *root;
// Buffer to read dog names into
char name[MAXCHAR];
int main(int argc, char *argv[])
{
// Check for command line args
if (argc != 2)
{
printf("Usage: ./trie infile\n");
return 1;
}
// File with names
FILE *infile = fopen(argv[1], "r");
if (!infile)
{
printf("Error opening file!\n");
return 1;
}
// Allocate root of trie
root = malloc(sizeof(node));
if (root == NULL)
{
return 1;
}
root->is_word = false;
for (int i = 0; i < SIZE_OF_ALPHABET; i++)
{
root->children[i] = NULL;
}
// Add words to the trie
while (fscanf(infile, "%s", name) == 1)
{
node *cursor = root;
for (int i = 0, n = strlen(name); i < n; i++)
{
int index = tolower(name[i]) - 'a';
if (cursor->children[index] == NULL)
{
// Make node
node *new = malloc(sizeof(node));
new->is_word = false;
for (int j = 0; j < SIZE_OF_ALPHABET; j++)
{
new->children[j] = NULL;
}
cursor->children[index] = new;
}
// Go to node which we may have just been made
cursor = cursor->children[index];
}
// if we are at the end of the word, mark it as being a word
cursor->is_word = true;
}
if (check(get_string("Check word: ")))
{
printf("Found!\n");
}
else
{
printf("Not Found.\n");
}
if (!unload())
{
printf("Problem freeing memory!\n");
return 1;
}
fclose(infile);
}
// TODO: Complete the check function, return true if found, false if not found
bool check(char *word)
{
node *cursor = root;
for (int i = 0; i < strlen(word); i++)
{
int index = tolower(word[i]) - 'a';
if (index < 0 || index > 25)
{
return false;
}
if (cursor -> children[index] == NULL)
{
return false;
}
cursor = cursor -> children[index];
}
return cursor -> is_word;
}
// Unload trie from memory
bool unload(void)
{
// The recursive function handles all of the freeing
unloader(root);
return true;
}
void unloader(node *current)
{
// Iterate over all the children to see if they point to anything and go
// there if they do point
for (int i = 0; i < SIZE_OF_ALPHABET; i++)
{
if (current->children[i] != NULL)
{
unloader(current->children[i]);
}
}
// After we check all the children point to null we can get rid of the node
// and return to the previous iteration of this function.
free(current);
}