#include #include #include #define MAX_TEXT 256 // Структура вузла дерева typedef struct Node { char text[MAX_TEXT]; struct Node *yes; struct Node *no; } Node; // Функція для створення нового вузла Node* createNode(const char* text) { Node* node = (Node*)malloc(sizeof(Node)); if (node) { strncpy(node->text, text, MAX_TEXT); node->yes = NULL; node->no = NULL; } return node; } // Завантаження дерева з файлу Node* loadTree(FILE *file) { char line[MAX_TEXT]; if (!fgets(line, sizeof(line), file)) { return NULL; } line[strcspn(line, "\n")] = 0; // Видаляємо новий рядок // Визначаємо, чи це листовий вузол if (line[0] == '*') { return createNode(line + 1); // Видаляємо символ '*' на початку } // Створюємо внутрішній вузол з двома піддеревами Node *node = createNode(line); node->yes = loadTree(file); node->no = loadTree(file); return node; } // Функція для підрахунку вузлів (листових та внутрішніх) void countNodes(Node* root, int* leafCount, int* internalCount) { if (root == NULL) { return; } if (root->yes == NULL && root->no == NULL) { (*leafCount)++; } else { (*internalCount)++; countNodes(root->yes, leafCount, internalCount); countNodes(root->no, leafCount, internalCount); } } // Функція для проведення діалогу з користувачем void interact(Node* root) { Node* current = root; while (current->yes != NULL && current->no != NULL) { printf("Odpovedajte 'a' pre prvu moznost alebo 'n' pre druhu moznost.\n"); printf("%s (a/n): ", current->text); char answer; // Читання одного символа для відповіді int res = fgetc(stdin); // Використовуємо fgetc для точного контролю вводу // Пропускаємо всі зайві символи нового рядка або пробіли while (res == '\n' || res == ' ' || res == '\t') { res = fgetc(stdin); } if (res == EOF) { printf("Некоректна відповідь! Завершення програми.\n"); return; } answer = (char)res; // Зберігаємо введений символ if (answer == 'a') { current = current->yes; } else if (answer == 'n') { current = current->no; } else { printf("Некоректна відповідь! Завершення програми.\n"); return; } } // Коли досягнуто листового вузла (товар) printf("%s\n", current->text); } // Функція для очищення пам'яті дерева void freeTree(Node* root) { if (root == NULL) { return; } freeTree(root->yes); freeTree(root->no); free(root); } int main(int argc, char *argv[]) { // Відкриваємо файл або використовуємо стандартний вхід FILE *file; if (argc > 1) { file = fopen(argv[1], "r"); if (!file) { printf("Помилка: не вдалося відкрити файл %s.\n", argv[1]); return 1; } } else { file = stdin; // Використовуємо стандартний вхід, якщо файл не заданий } // Завантажуємо дерево з файлу Node* root = loadTree(file); if (file != stdin) fclose(file); // Перевірка на успішне завантаження дерева if (!root) { printf("Помилка: дерево не було завантажене.\n"); return 1; } // Підрахунок вузлів int leafCount = 0, internalCount = 0; countNodes(root, &leafCount, &internalCount); printf("Zasadny vykon\n"); printf("Zagolna kilkist tovariv (listovykh vuzliv): %d\n", leafCount); printf("Kilkist pytan (vnutrishnikh vuzliv): %d\n", internalCount); // Інтерактивна взаємодія з користувачем printf("Pochynayemo dialoh...\n"); interact(root); // Очищення пам'яті freeTree(root); printf("Program zaversheno uspishno.\n"); return 0; }