#include #include #include // Структура вузла для дерева знань typedef struct Node { char *question_or_answer; struct Node *yes_branch; struct Node *no_branch; } Node; // Функція для створення нового вузла Node* createNode(char *text) { Node *newNode = (Node*)malloc(sizeof(Node)); if (!newNode) { printf("Помилка виділення пам'яті.\n"); exit(0); } newNode->question_or_answer = strdup(text); // Копіюємо текст у вузол newNode->yes_branch = NULL; newNode->no_branch = NULL; return newNode; } // Функція для побудови дерева з бази знань Node* buildTree(FILE *file) { char buffer[256]; if (!fgets(buffer, sizeof(buffer), file) || buffer[0] == '\n') { return NULL; // Кінець бази знань } buffer[strcspn(buffer, "\n")] = '\0'; // Видаляємо символ нового рядка Node *node = NULL; if (buffer[0] == '*') { // Якщо рядок починається з '*', це кінцева відповідь node = createNode(buffer + 1); // Створюємо вузол з відповіддю, без '*' } else { // Інакше це питання node = createNode(buffer); // Створюємо вузол з питанням node->yes_branch = buildTree(file); // Рекурсивно будуємо гілку "так" node->no_branch = buildTree(file); // Рекурсивно будуємо гілку "ні" } return node; } // Функція для підрахунку кількості кінцевих відповідей (листків) у дереві int countAnswers(Node *node) { if (node == NULL) return 0; if (node->yes_branch == NULL && node->no_branch == NULL) return 1; // Листок return countAnswers(node->yes_branch) + countAnswers(node->no_branch); } // Функція для діалогу з користувачем void runExpertSystem(Node *node) { while (node != NULL) { // Якщо вузол є кінцевою відповіддю, виводимо її і завершуємо if (node->yes_branch == NULL && node->no_branch == NULL) { printf("Відповідь: %s\n", node->question_or_answer); return; } // Виводимо питання printf("%s (Введіть 'a' для так або 'n' для ні): ", node->question_or_answer); // Читаємо відповідь користувача char choice; scanf(" %c", &choice); // Обробка відповіді switch (choice) { case 'a': // Якщо "так" node = node->yes_branch; break; case 'n': // Якщо "ні" node = node->no_branch; break; default: // Некоректний ввід printf("Некоректне значення. Завершення програми.\n"); return; } } } // Рекурсивна функція для звільнення пам'яті void freeTree(Node *node) { if (node == NULL) return; freeTree(node->yes_branch); freeTree(node->no_branch); free(node->question_or_answer); // Звільняємо текст питання/відповіді free(node); // Звільняємо сам вузол } int main() { // Відкриваємо файл із базою знань FILE *file = fopen("data.txt", "r"); if (!file) { printf("Не вдалося відкрити файл бази знань.\n"); return 1; } // Будуємо дерево знань з файлу Node *root = buildTree(file); fclose(file); // Перевірка, чи дерево успішно збудовано if (root == NULL) { printf("Помилка завантаження бази знань.\n"); return 1; } // Рахуємо кількість видів у базі знань int totalAnswers = countAnswers(root); printf("Експертна система знає %d видів.\n", totalAnswers); // Запускаємо діалог з користувачем runExpertSystem(root); // Звільняємо пам'ять freeTree(root); return 0; }