usaa24/cv7/program.c

120 lines
6.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 256
// Структура для вузла дерева
struct tree {
char value[SIZE]; // Текст питання або твердження
struct tree *left; // Лівий підвузол
struct tree *right; // Правий підвузол
int id; // Ідентифікатор вузла
};
// Функція для знищення дерева та звільнення пам'яті
void destroy_tree(struct tree *tree) {
if (tree == NULL) return; // Якщо вузол порожній, нічого не робимо
destroy_tree(tree->left); // Рекурсивно знищуємо лівий підвузол
destroy_tree(tree->right); // Рекурсивно знищуємо правий підвузол
free(tree); // Звільняємо пам'ять, виділену для поточного вузла
}
// Функція для підрахунку кількості листових елементів (відповідей) в дереві
int count_items(struct tree *tree) {
if (tree == NULL) return 0; // Якщо вузол порожній, повертаємо 0
if (tree->left == NULL && tree->right == NULL) return 1; // Якщо вузол є листом (не має підвузлів), то це відповідь
return count_items(tree->left) + count_items(tree->right); // Рекурсивно підраховуємо кількість листових елементів
}
// Основна функція для запуску системи рішень
void run_system(struct tree *node) {
if (node == NULL) return; // Якщо вузол порожній, припиняємо виконання
int empty_lines = 0; // Лічильник порожніх рядків
int first_prompt = 1; // Флаг для виведення першого підказки
// Основний цикл, який буде працювати, поки є вузли в дереві
while (node != NULL) {
// Якщо вузол є листом (в кінці дерева)
if (node->left == NULL && node->right == NULL) {
printf("%s", node->value); // Виводимо відповідь
printf("Koniec\n"); // Завершуємо програму
return;
}
// Перший запит до користувача, вибір між двома варіантами
if (first_prompt) {
printf("Odpovedajte 'a' pre prvu moznost alebo 'n' pre druhu moznost.\n");
first_prompt = 0; // Встановлюємо флаг, щоб підказка виводилась тільки один раз
}
printf("%s", node->value); // Виводимо питання
char answer;
int result = scanf(" %c", &answer); // Читаємо відповідь користувача
// Перевірка на кінець вводу або два порожні рядки поспіль
if (result == EOF || (answer == '\n' && ++empty_lines >= 2)) {
printf("Koniec vstupu\n");
return; // Завершуємо виконання програми
}
// Обробка відповіді користувача
if (answer == 'a') {
empty_lines = 0; // Скидаємо лічильник порожніх рядків
node = node->left; // Переходимо до лівого підвузла
} else if (answer == 'n') {
empty_lines = 0; // Скидаємо лічильник порожніх рядків
node = node->right; // Переходимо до правого підвузла
} else {
printf("Nerozumiem\n"); // Якщо відповідь неправильна
return; // Завершуємо програму
}
}
}
// Функція для читання дерева з вводу
struct tree* read_tree(int *counter) {
char buffer[SIZE]; // Буфер для зберігання рядка
if (fgets(buffer, SIZE, stdin) == NULL || buffer[0] == '\n') {
return NULL; // Якщо рядок порожній або не вдалося прочитати, повертаємо NULL
}
struct tree *node = calloc(1, sizeof(struct tree)); // Створюємо новий вузол
if (node == NULL) {
return NULL; // Якщо пам'ять не вдалося аллокувати, повертаємо NULL
}
strcpy(node->value, buffer); // Копіюємо значення в поле value
node->id = (*counter)++; // Присвоюємо унікальний ідентифікатор вузла
// Якщо це не лист, то читаємо лівий та правий підвузли
if (buffer[0] != '*') {
node->left = read_tree(counter); // Рекурсивно читаємо лівий підвузол
node->right = read_tree(counter); // Рекурсивно читаємо правий підвузол
}
return node; // Повертаємо створений вузол
}
int main() {
int counter = 0; // Лічильник для присвоєння ідентифікаторів вузлам
struct tree *root = read_tree(&counter); // Читаємо дерево з вводу
printf("Expert z bufetu to vie.\n");
if (root == NULL) {
printf("Chybna databaza\n");
return 0; // Якщо дерево порожнє, завершуємо виконання
}
// Підрахуємо кількість всіх елементів (питань або відповідей) у дереві
int items_count = count_items(root);
printf("Pozna %d druhov ovocia a zeleniny.\n", items_count); // Виводимо кількість елементів
run_system(root); // Запускаємо систему рішень
destroy_tree(root); // Знищуємо дерево після завершення роботи
return 0;
}