1*061da546Spatrick //===-- dictionary.c ---------------------------------------------*- C -*-===//
2*061da546Spatrick //
3*061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5*061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*061da546Spatrick //
7*061da546Spatrick //===---------------------------------------------------------------------===//
8*061da546Spatrick #include <ctype.h>
9*061da546Spatrick #include <stdio.h>
10*061da546Spatrick #include <stdlib.h>
11*061da546Spatrick #include <string.h>
12*061da546Spatrick
13*061da546Spatrick typedef struct tree_node {
14*061da546Spatrick const char *word;
15*061da546Spatrick struct tree_node *left;
16*061da546Spatrick struct tree_node *right;
17*061da546Spatrick } tree_node;
18*061da546Spatrick
19*061da546Spatrick /* Given a char*, returns a substring that starts at the first
20*061da546Spatrick alphabet character and ends at the last alphabet character, i.e. it
21*061da546Spatrick strips off beginning or ending quotes, punctuation, etc. */
22*061da546Spatrick
strip(char ** word)23*061da546Spatrick char *strip(char **word) {
24*061da546Spatrick char *start = *word;
25*061da546Spatrick int len = strlen(start);
26*061da546Spatrick char *end = start + len - 1;
27*061da546Spatrick
28*061da546Spatrick while ((start < end) && (!isalpha(start[0])))
29*061da546Spatrick start++;
30*061da546Spatrick
31*061da546Spatrick while ((end > start) && (!isalpha(end[0])))
32*061da546Spatrick end--;
33*061da546Spatrick
34*061da546Spatrick if (start > end)
35*061da546Spatrick return NULL;
36*061da546Spatrick
37*061da546Spatrick end[1] = '\0';
38*061da546Spatrick *word = start;
39*061da546Spatrick
40*061da546Spatrick return start;
41*061da546Spatrick }
42*061da546Spatrick
43*061da546Spatrick /* Given a binary search tree (sorted alphabetically by the word at
44*061da546Spatrick each node), and a new word, inserts the word at the appropriate
45*061da546Spatrick place in the tree. */
46*061da546Spatrick
insert(tree_node * root,char * word)47*061da546Spatrick void insert(tree_node *root, char *word) {
48*061da546Spatrick if (root == NULL)
49*061da546Spatrick return;
50*061da546Spatrick
51*061da546Spatrick int compare_value = strcmp(word, root->word);
52*061da546Spatrick
53*061da546Spatrick if (compare_value == 0)
54*061da546Spatrick return;
55*061da546Spatrick
56*061da546Spatrick if (compare_value < 0) {
57*061da546Spatrick if (root->left != NULL)
58*061da546Spatrick insert(root->left, word);
59*061da546Spatrick else {
60*061da546Spatrick tree_node *new_node = (tree_node *)malloc(sizeof(tree_node));
61*061da546Spatrick new_node->word = strdup(word);
62*061da546Spatrick new_node->left = NULL;
63*061da546Spatrick new_node->right = NULL;
64*061da546Spatrick root->left = new_node;
65*061da546Spatrick }
66*061da546Spatrick } else {
67*061da546Spatrick if (root->right != NULL)
68*061da546Spatrick insert(root->right, word);
69*061da546Spatrick else {
70*061da546Spatrick tree_node *new_node = (tree_node *)malloc(sizeof(tree_node));
71*061da546Spatrick new_node->word = strdup(word);
72*061da546Spatrick new_node->left = NULL;
73*061da546Spatrick new_node->right = NULL;
74*061da546Spatrick root->right = new_node;
75*061da546Spatrick }
76*061da546Spatrick }
77*061da546Spatrick }
78*061da546Spatrick
79*061da546Spatrick /* Read in a text file and storea all the words from the file in a
80*061da546Spatrick binary search tree. */
81*061da546Spatrick
populate_dictionary(tree_node ** dictionary,char * filename)82*061da546Spatrick void populate_dictionary(tree_node **dictionary, char *filename) {
83*061da546Spatrick FILE *in_file;
84*061da546Spatrick char word[1024];
85*061da546Spatrick
86*061da546Spatrick in_file = fopen(filename, "r");
87*061da546Spatrick if (in_file) {
88*061da546Spatrick while (fscanf(in_file, "%s", word) == 1) {
89*061da546Spatrick char *new_word = (strdup(word));
90*061da546Spatrick new_word = strip(&new_word);
91*061da546Spatrick if (*dictionary == NULL) {
92*061da546Spatrick tree_node *new_node = (tree_node *)malloc(sizeof(tree_node));
93*061da546Spatrick new_node->word = new_word;
94*061da546Spatrick new_node->left = NULL;
95*061da546Spatrick new_node->right = NULL;
96*061da546Spatrick *dictionary = new_node;
97*061da546Spatrick } else
98*061da546Spatrick insert(*dictionary, new_word);
99*061da546Spatrick }
100*061da546Spatrick }
101*061da546Spatrick }
102*061da546Spatrick
103*061da546Spatrick /* Given a binary search tree and a word, search for the word
104*061da546Spatrick in the binary search tree. */
105*061da546Spatrick
find_word(tree_node * dictionary,char * word)106*061da546Spatrick int find_word(tree_node *dictionary, char *word) {
107*061da546Spatrick if (!word || !dictionary)
108*061da546Spatrick return 0;
109*061da546Spatrick
110*061da546Spatrick int compare_value = strcmp(word, dictionary->word);
111*061da546Spatrick
112*061da546Spatrick if (compare_value == 0)
113*061da546Spatrick return 1;
114*061da546Spatrick else if (compare_value < 0)
115*061da546Spatrick return find_word(dictionary->left, word);
116*061da546Spatrick else
117*061da546Spatrick return find_word(dictionary->right, word);
118*061da546Spatrick }
119*061da546Spatrick
120*061da546Spatrick /* Print out the words in the binary search tree, in sorted order. */
121*061da546Spatrick
print_tree(tree_node * dictionary)122*061da546Spatrick void print_tree(tree_node *dictionary) {
123*061da546Spatrick if (!dictionary)
124*061da546Spatrick return;
125*061da546Spatrick
126*061da546Spatrick if (dictionary->left)
127*061da546Spatrick print_tree(dictionary->left);
128*061da546Spatrick
129*061da546Spatrick printf("%s\n", dictionary->word);
130*061da546Spatrick
131*061da546Spatrick if (dictionary->right)
132*061da546Spatrick print_tree(dictionary->right);
133*061da546Spatrick }
134*061da546Spatrick
main(int argc,char ** argv)135*061da546Spatrick int main(int argc, char **argv) {
136*061da546Spatrick tree_node *dictionary = NULL;
137*061da546Spatrick char buffer[1024];
138*061da546Spatrick char *filename;
139*061da546Spatrick int done = 0;
140*061da546Spatrick
141*061da546Spatrick if (argc == 2)
142*061da546Spatrick filename = argv[1];
143*061da546Spatrick
144*061da546Spatrick if (!filename)
145*061da546Spatrick return -1;
146*061da546Spatrick
147*061da546Spatrick populate_dictionary(&dictionary, filename);
148*061da546Spatrick fprintf(stdout, "Dictionary loaded.\nEnter search word: ");
149*061da546Spatrick while (!done && fgets(buffer, sizeof(buffer), stdin)) {
150*061da546Spatrick char *word = buffer;
151*061da546Spatrick int len = strlen(word);
152*061da546Spatrick int i;
153*061da546Spatrick
154*061da546Spatrick for (i = 0; i < len; ++i)
155*061da546Spatrick word[i] = tolower(word[i]);
156*061da546Spatrick
157*061da546Spatrick if ((len > 0) && (word[len - 1] == '\n')) {
158*061da546Spatrick word[len - 1] = '\0';
159*061da546Spatrick len = len - 1;
160*061da546Spatrick }
161*061da546Spatrick
162*061da546Spatrick if (find_word(dictionary, word))
163*061da546Spatrick fprintf(stdout, "Yes!\n");
164*061da546Spatrick else
165*061da546Spatrick fprintf(stdout, "No!\n");
166*061da546Spatrick
167*061da546Spatrick fprintf(stdout, "Enter search word: ");
168*061da546Spatrick }
169*061da546Spatrick
170*061da546Spatrick fprintf(stdout, "\n");
171*061da546Spatrick return 0;
172*061da546Spatrick }
173