12e9dd93eSCaroline Tice //===-- dictionary.c ---------------------------------------------*- C -*-===//
22e9dd93eSCaroline Tice //
3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
62e9dd93eSCaroline Tice //
72e9dd93eSCaroline Tice //===---------------------------------------------------------------------===//
82e9dd93eSCaroline Tice #include <ctype.h>
9b9c1b51eSKate Stone #include <stdio.h>
10b9c1b51eSKate Stone #include <stdlib.h>
112e9dd93eSCaroline Tice #include <string.h>
122e9dd93eSCaroline Tice
13b9c1b51eSKate Stone typedef struct tree_node {
142e9dd93eSCaroline Tice const char *word;
152e9dd93eSCaroline Tice struct tree_node *left;
162e9dd93eSCaroline Tice struct tree_node *right;
172e9dd93eSCaroline Tice } tree_node;
182e9dd93eSCaroline Tice
192e9dd93eSCaroline Tice /* Given a char*, returns a substring that starts at the first
202e9dd93eSCaroline Tice alphabet character and ends at the last alphabet character, i.e. it
212e9dd93eSCaroline Tice strips off beginning or ending quotes, punctuation, etc. */
222e9dd93eSCaroline Tice
strip(char ** word)23b9c1b51eSKate Stone char *strip(char **word) {
242e9dd93eSCaroline Tice char *start = *word;
252e9dd93eSCaroline Tice int len = strlen(start);
262e9dd93eSCaroline Tice char *end = start + len - 1;
272e9dd93eSCaroline Tice
282e9dd93eSCaroline Tice while ((start < end) && (!isalpha(start[0])))
292e9dd93eSCaroline Tice start++;
302e9dd93eSCaroline Tice
312e9dd93eSCaroline Tice while ((end > start) && (!isalpha(end[0])))
322e9dd93eSCaroline Tice end--;
332e9dd93eSCaroline Tice
342e9dd93eSCaroline Tice if (start > end)
352e9dd93eSCaroline Tice return NULL;
362e9dd93eSCaroline Tice
372e9dd93eSCaroline Tice end[1] = '\0';
382e9dd93eSCaroline Tice *word = start;
392e9dd93eSCaroline Tice
402e9dd93eSCaroline Tice return start;
412e9dd93eSCaroline Tice }
422e9dd93eSCaroline Tice
432e9dd93eSCaroline Tice /* Given a binary search tree (sorted alphabetically by the word at
442e9dd93eSCaroline Tice each node), and a new word, inserts the word at the appropriate
452e9dd93eSCaroline Tice place in the tree. */
462e9dd93eSCaroline Tice
insert(tree_node * root,char * word)47b9c1b51eSKate Stone void insert(tree_node *root, char *word) {
482e9dd93eSCaroline Tice if (root == NULL)
492e9dd93eSCaroline Tice return;
502e9dd93eSCaroline Tice
512e9dd93eSCaroline Tice int compare_value = strcmp(word, root->word);
522e9dd93eSCaroline Tice
532e9dd93eSCaroline Tice if (compare_value == 0)
542e9dd93eSCaroline Tice return;
552e9dd93eSCaroline Tice
56b9c1b51eSKate Stone if (compare_value < 0) {
572e9dd93eSCaroline Tice if (root->left != NULL)
582e9dd93eSCaroline Tice insert(root->left, word);
59b9c1b51eSKate Stone else {
602e9dd93eSCaroline Tice tree_node *new_node = (tree_node *)malloc(sizeof(tree_node));
612e9dd93eSCaroline Tice new_node->word = strdup(word);
622e9dd93eSCaroline Tice new_node->left = NULL;
632e9dd93eSCaroline Tice new_node->right = NULL;
642e9dd93eSCaroline Tice root->left = new_node;
652e9dd93eSCaroline Tice }
66b9c1b51eSKate Stone } else {
672e9dd93eSCaroline Tice if (root->right != NULL)
682e9dd93eSCaroline Tice insert(root->right, word);
69b9c1b51eSKate Stone else {
702e9dd93eSCaroline Tice tree_node *new_node = (tree_node *)malloc(sizeof(tree_node));
712e9dd93eSCaroline Tice new_node->word = strdup(word);
722e9dd93eSCaroline Tice new_node->left = NULL;
732e9dd93eSCaroline Tice new_node->right = NULL;
742e9dd93eSCaroline Tice root->right = new_node;
752e9dd93eSCaroline Tice }
762e9dd93eSCaroline Tice }
772e9dd93eSCaroline Tice }
782e9dd93eSCaroline Tice
792e9dd93eSCaroline Tice /* Read in a text file and storea all the words from the file in a
802e9dd93eSCaroline Tice binary search tree. */
812e9dd93eSCaroline Tice
populate_dictionary(tree_node ** dictionary,char * filename)82b9c1b51eSKate Stone void populate_dictionary(tree_node **dictionary, char *filename) {
832e9dd93eSCaroline Tice FILE *in_file;
842e9dd93eSCaroline Tice char word[1024];
852e9dd93eSCaroline Tice
862e9dd93eSCaroline Tice in_file = fopen(filename, "r");
87b9c1b51eSKate Stone if (in_file) {
88b9c1b51eSKate Stone while (fscanf(in_file, "%s", word) == 1) {
892e9dd93eSCaroline Tice char *new_word = (strdup(word));
902e9dd93eSCaroline Tice new_word = strip(&new_word);
91b9c1b51eSKate Stone if (*dictionary == NULL) {
922e9dd93eSCaroline Tice tree_node *new_node = (tree_node *)malloc(sizeof(tree_node));
932e9dd93eSCaroline Tice new_node->word = new_word;
942e9dd93eSCaroline Tice new_node->left = NULL;
952e9dd93eSCaroline Tice new_node->right = NULL;
962e9dd93eSCaroline Tice *dictionary = new_node;
97b9c1b51eSKate Stone } else
982e9dd93eSCaroline Tice insert(*dictionary, new_word);
992e9dd93eSCaroline Tice }
1002e9dd93eSCaroline Tice }
1012e9dd93eSCaroline Tice }
1022e9dd93eSCaroline Tice
1032e9dd93eSCaroline Tice /* Given a binary search tree and a word, search for the word
1042e9dd93eSCaroline Tice in the binary search tree. */
1052e9dd93eSCaroline Tice
find_word(tree_node * dictionary,char * word)106b9c1b51eSKate Stone int find_word(tree_node *dictionary, char *word) {
1072e9dd93eSCaroline Tice if (!word || !dictionary)
1082e9dd93eSCaroline Tice return 0;
1092e9dd93eSCaroline Tice
1102e9dd93eSCaroline Tice int compare_value = strcmp(word, dictionary->word);
1112e9dd93eSCaroline Tice
1122e9dd93eSCaroline Tice if (compare_value == 0)
1132e9dd93eSCaroline Tice return 1;
1142e9dd93eSCaroline Tice else if (compare_value < 0)
1152e9dd93eSCaroline Tice return find_word(dictionary->left, word);
1162e9dd93eSCaroline Tice else
1172e9dd93eSCaroline Tice return find_word(dictionary->right, word);
1182e9dd93eSCaroline Tice }
1192e9dd93eSCaroline Tice
1202e9dd93eSCaroline Tice /* Print out the words in the binary search tree, in sorted order. */
1212e9dd93eSCaroline Tice
print_tree(tree_node * dictionary)122b9c1b51eSKate Stone void print_tree(tree_node *dictionary) {
1232e9dd93eSCaroline Tice if (!dictionary)
1242e9dd93eSCaroline Tice return;
1252e9dd93eSCaroline Tice
1262e9dd93eSCaroline Tice if (dictionary->left)
1272e9dd93eSCaroline Tice print_tree(dictionary->left);
1282e9dd93eSCaroline Tice
1292e9dd93eSCaroline Tice printf("%s\n", dictionary->word);
1302e9dd93eSCaroline Tice
1312e9dd93eSCaroline Tice if (dictionary->right)
1322e9dd93eSCaroline Tice print_tree(dictionary->right);
1332e9dd93eSCaroline Tice }
1342e9dd93eSCaroline Tice
main(int argc,char ** argv)135b9c1b51eSKate Stone int main(int argc, char **argv) {
1362e9dd93eSCaroline Tice tree_node *dictionary = NULL;
1372e9dd93eSCaroline Tice char buffer[1024];
1382e9dd93eSCaroline Tice char *filename;
1392e9dd93eSCaroline Tice int done = 0;
1402e9dd93eSCaroline Tice
1412e9dd93eSCaroline Tice if (argc == 2)
1422e9dd93eSCaroline Tice filename = argv[1];
1432e9dd93eSCaroline Tice
1442e9dd93eSCaroline Tice if (!filename)
1452e9dd93eSCaroline Tice return -1;
1462e9dd93eSCaroline Tice
1472e9dd93eSCaroline Tice populate_dictionary(&dictionary, filename);
1482e9dd93eSCaroline Tice fprintf(stdout, "Dictionary loaded.\nEnter search word: ");
149b9c1b51eSKate Stone while (!done && fgets(buffer, sizeof(buffer), stdin)) {
1502e9dd93eSCaroline Tice char *word = buffer;
1512e9dd93eSCaroline Tice int len = strlen(word);
1522e9dd93eSCaroline Tice int i;
1532e9dd93eSCaroline Tice
1542e9dd93eSCaroline Tice for (i = 0; i < len; ++i)
1552e9dd93eSCaroline Tice word[i] = tolower(word[i]);
1562e9dd93eSCaroline Tice
157b9c1b51eSKate Stone if ((len > 0) && (word[len - 1] == '\n')) {
1582e9dd93eSCaroline Tice word[len - 1] = '\0';
1592e9dd93eSCaroline Tice len = len - 1;
1602e9dd93eSCaroline Tice }
1612e9dd93eSCaroline Tice
1622e9dd93eSCaroline Tice if (find_word(dictionary, word))
1632e9dd93eSCaroline Tice fprintf(stdout, "Yes!\n");
1642e9dd93eSCaroline Tice else
1652e9dd93eSCaroline Tice fprintf(stdout, "No!\n");
1662e9dd93eSCaroline Tice
1672e9dd93eSCaroline Tice fprintf(stdout, "Enter search word: ");
1682e9dd93eSCaroline Tice }
1692e9dd93eSCaroline Tice
1702e9dd93eSCaroline Tice fprintf(stdout, "\n");
1712e9dd93eSCaroline Tice return 0;
1722e9dd93eSCaroline Tice }
173