diff --git a/cv7/program.c b/cv7/program.c index 9100b11..7ec441a 100644 --- a/cv7/program.c +++ b/cv7/program.c @@ -2,94 +2,108 @@ #include #include -#define SIZE 256 +#define MAX_SIZE 256 -// Структура узла бинарного дерева -struct strom { - char otazka[SIZE]; - struct strom* ano; - struct strom* nie; +struct node { + char value[MAX_SIZE]; + struct node *left; + struct node *right; + int id; }; -// Функция для чтения базы правил из стандартного ввода -struct strom* nacitaj_strom() { - char buffer[SIZE]; - if (!fgets(buffer, SIZE, stdin) || buffer[0] == '\n') { - return NULL; // Конец базы данных или пустая строка +struct node* read_tree(int *id_counter) { + char line[MAX_SIZE]; + + if (fgets(line, MAX_SIZE, stdin) == NULL || line[0] == '\n') { + return NULL; } - struct strom* uzol = malloc(sizeof(struct strom)); - if (!uzol) { - printf("Chyba: nedostatok pamäte.\n"); - exit(1); - } - strcpy(uzol->otazka, buffer); - - if (buffer[0] == '*') { - uzol->ano = uzol->nie = NULL; // Это лист (ответ) - } else { - uzol->ano = nacitaj_strom(); // Чтение ветви для "да" - uzol->nie = nacitaj_strom(); // Чтение ветви для "нет" + struct node *new_node = (struct node*)malloc(sizeof(struct node)); + if (new_node == NULL) { + return NULL; } - return uzol; + strcpy(new_node->value, line); + new_node->id = (*id_counter)++; + + if (line[0] != '*') { + new_node->left = read_tree(id_counter); + new_node->right = read_tree(id_counter); + } + + return new_node; } -// Функция для освобождения памяти дерева -void znic_strom(struct strom* uzol) { - if (uzol) { - znic_strom(uzol->ano); - znic_strom(uzol->nie); - free(uzol); - } +void free_tree(struct node *root) { + if (root == NULL) return; + free_tree(root->left); + free_tree(root->right); + free(root); } -// Функция для взаимодействия с пользователем (прохождение дерева) -void spusti_expert_system(struct strom* uzol) { - if (!uzol) return; +int count_items(struct node *root) { + if (root == NULL) return 0; + if (root->left == NULL && root->right == NULL) return 1; + return count_items(root->left) + count_items(root->right); +} - printf("%s", uzol->otazka); - if (!uzol->ano && !uzol->nie) { - printf("Koniec\n"); // Окончательный ответ с сообщением об окончании - return; - } +void start_system(struct node *current_node) { + if (current_node == NULL) return; - char odpoved; - if (scanf(" %c", &odpoved) != 1 || (odpoved != 'a' && odpoved != 'n')) { - printf("Nerozumiem\n"); - spusti_expert_system(uzol); // Повторный вызов для текущего вопроса при некорректном ответе - } else { - if (odpoved == 'a') { - spusti_expert_system(uzol->ano); + int blank_lines = 0; + int is_first_prompt = 1; + + while (current_node != NULL) { + if (current_node->left == NULL && current_node->right == NULL) { + printf("%s", current_node->value); + printf("Koniec\n"); + return; + } + + if (is_first_prompt) { + printf("Odpovedajte 'a' pre prvu moznost alebo 'n' pre druhu moznost.\n"); + is_first_prompt = 0; + } + + printf("%s", current_node->value); + + char response; + int result = scanf(" %c", &response); + + if (result == EOF || (response == '\n' && ++blank_lines >= 2)) { + printf("Koniec vstupu\n"); + return; + } + + if (response == 'a') { + blank_lines = 0; + current_node = current_node->left; + } else if (response == 'n') { + blank_lines = 0; + current_node = current_node->right; } else { - spusti_expert_system(uzol->nie); + printf("Nerozumiem\n"); + return; } } } -// Функция для подсчета листьев дерева (окончательных ответов) -int pocet_listov(struct strom* uzol) { - if (!uzol) return 0; - if (!uzol->ano && !uzol->nie) return 1; - return pocet_listov(uzol->ano) + pocet_listov(uzol->nie); -} - -// Главная функция int main() { - struct strom* databaza_znalosti = nacitaj_strom(); + int counter = 0; + struct node *root = read_tree(&counter); - if (!databaza_znalosti) { - printf("Chyba: databáza je prázdna alebo nesprávne formátovaná.\n"); - return 1; + printf("Expert z bufetu to vie.\n"); + + if (root == NULL) { + printf("Chybna databaza\n"); + return 0; } - int pocet_tovarov = pocet_listov(databaza_znalosti); - printf("Expert z bufetu to vie.\n"); - printf("Pozna %d druhov ovocia a zeleniny.\n", pocet_tovarov); - printf("Odpovedajte 'a' pre prvu moznost alebo 'n' pre druhu moznost.\n"); + int item_count = count_items(root); + printf("Pozna %d druhov ovocia a zeleniny.\n", item_count); - spusti_expert_system(databaza_znalosti); - znic_strom(databaza_znalosti); + start_system(root); + free_tree(root); return 0; }