#include #include #include #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; }