| //===-- dictionary.c ---------------------------------------------*- C -*-===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===---------------------------------------------------------------------===// | |
| #include <ctype.h> | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| typedef struct tree_node { | |
| const char *word; | |
| struct tree_node *left; | |
| struct tree_node *right; | |
| } tree_node; | |
| /* Given a char*, returns a substring that starts at the first | |
| alphabet character and ends at the last alphabet character, i.e. it | |
| strips off beginning or ending quotes, punctuation, etc. */ | |
| char *strip(char **word) { | |
| char *start = *word; | |
| int len = strlen(start); | |
| char *end = start + len - 1; | |
| while ((start < end) && (!isalpha(start[0]))) | |
| start++; | |
| while ((end > start) && (!isalpha(end[0]))) | |
| end--; | |
| if (start > end) | |
| return NULL; | |
| end[1] = '\0'; | |
| *word = start; | |
| return start; | |
| } | |
| /* Given a binary search tree (sorted alphabetically by the word at | |
| each node), and a new word, inserts the word at the appropriate | |
| place in the tree. */ | |
| void insert(tree_node *root, char *word) { | |
| if (root == NULL) | |
| return; | |
| int compare_value = strcmp(word, root->word); | |
| if (compare_value == 0) | |
| return; | |
| if (compare_value < 0) { | |
| if (root->left != NULL) | |
| insert(root->left, word); | |
| else { | |
| tree_node *new_node = (tree_node *)malloc(sizeof(tree_node)); | |
| new_node->word = strdup(word); | |
| new_node->left = NULL; | |
| new_node->right = NULL; | |
| root->left = new_node; | |
| } | |
| } else { | |
| if (root->right != NULL) | |
| insert(root->right, word); | |
| else { | |
| tree_node *new_node = (tree_node *)malloc(sizeof(tree_node)); | |
| new_node->word = strdup(word); | |
| new_node->left = NULL; | |
| new_node->right = NULL; | |
| root->right = new_node; | |
| } | |
| } | |
| } | |
| /* Read in a text file and storea all the words from the file in a | |
| binary search tree. */ | |
| void populate_dictionary(tree_node **dictionary, char *filename) { | |
| FILE *in_file; | |
| char word[1024]; | |
| in_file = fopen(filename, "r"); | |
| if (in_file) { | |
| while (fscanf(in_file, "%s", word) == 1) { | |
| char *new_word = (strdup(word)); | |
| new_word = strip(&new_word); | |
| if (*dictionary == NULL) { | |
| tree_node *new_node = (tree_node *)malloc(sizeof(tree_node)); | |
| new_node->word = new_word; | |
| new_node->left = NULL; | |
| new_node->right = NULL; | |
| *dictionary = new_node; | |
| } else | |
| insert(*dictionary, new_word); | |
| } | |
| } | |
| } | |
| /* Given a binary search tree and a word, search for the word | |
| in the binary search tree. */ | |
| int find_word(tree_node *dictionary, char *word) { | |
| if (!word || !dictionary) | |
| return 0; | |
| int compare_value = strcmp(word, dictionary->word); | |
| if (compare_value == 0) | |
| return 1; | |
| else if (compare_value < 0) | |
| return find_word(dictionary->left, word); | |
| else | |
| return find_word(dictionary->right, word); | |
| } | |
| /* Print out the words in the binary search tree, in sorted order. */ | |
| void print_tree(tree_node *dictionary) { | |
| if (!dictionary) | |
| return; | |
| if (dictionary->left) | |
| print_tree(dictionary->left); | |
| printf("%s\n", dictionary->word); | |
| if (dictionary->right) | |
| print_tree(dictionary->right); | |
| } | |
| int main(int argc, char **argv) { | |
| tree_node *dictionary = NULL; | |
| char buffer[1024]; | |
| char *filename; | |
| int done = 0; | |
| if (argc == 2) | |
| filename = argv[1]; | |
| if (!filename) | |
| return -1; | |
| populate_dictionary(&dictionary, filename); | |
| fprintf(stdout, "Dictionary loaded.\nEnter search word: "); | |
| while (!done && fgets(buffer, sizeof(buffer), stdin)) { | |
| char *word = buffer; | |
| int len = strlen(word); | |
| int i; | |
| for (i = 0; i < len; ++i) | |
| word[i] = tolower(word[i]); | |
| if ((len > 0) && (word[len - 1] == '\n')) { | |
| word[len - 1] = '\0'; | |
| len = len - 1; | |
| } | |
| if (find_word(dictionary, word)) | |
| fprintf(stdout, "Yes!\n"); | |
| else | |
| fprintf(stdout, "No!\n"); | |
| fprintf(stdout, "Enter search word: "); | |
| } | |
| fprintf(stdout, "\n"); | |
| return 0; | |
| } |