From 11f5b61d7d1747f00301d981582f1bb5f8eda585 Mon Sep 17 00:00:00 2001 From: Yurii Chechur Date: Wed, 6 Nov 2024 07:18:40 +0000 Subject: [PATCH] Update cv7/program.c --- cv7/program.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/cv7/program.c b/cv7/program.c index e69de29..43867e3 100644 --- a/cv7/program.c +++ b/cv7/program.c @@ -0,0 +1,120 @@ +#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(1); + } + 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 (Введіть 'y' для так або 'n' для ні): ", node->question_or_answer); + + // Читаємо відповідь користувача + char choice; + scanf(" %c", &choice); + + // Обробка відповіді + switch (choice) { + case 'y': // Якщо "так" + 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; +}