#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() { char buffer[SIZE]; memset(buffer, 0, SIZE); // Read a line from stdin char* r = fgets(buffer, SIZE, stdin); if (r == NULL) { // fprintf(stderr, "Chybna databaza\n"); exit(1); // Exit the program if reading fails } // Allocate memory for a new tree node struct tree* node = calloc(1, sizeof(struct tree)); if (!node) { printf("Memory allocation failed!\n"); exit(1); } // Copy the input line into the node's value memcpy(node->value, buffer, SIZE); // If the line is a leaf node (starts with '*'), no further questions are needed if (buffer[0] == '*') { return node; // Leaf node, no need to read further } // If not a leaf, recursively read the left and right child nodes node->left = read_tree(); // Left child (yes answer) node->right = read_tree(); // Right child (no answer) return node; } int main() { int counter = 0; struct tree *root = read_tree(&counter); // Try reading the tree printf("Expert z bufetu to vie.\n"); // Check if the tree was read successfully if (root == NULL) { printf("Chybna databaza\n"); return 0; // Exit if the tree couldn't be read } // If the tree was successfully read, count the number of items int items_count = count_items(root); printf("Pozna %d druhov ovocia a zeleniny.\n", items_count); run_system(root); // Run the decision-making system destroy_tree(root); // Free the allocated memory for the tree return 0; }