usaa24/cv7/program.c
2024-11-08 10:21:48 +01:00

136 lines
4.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINE_LENGTH 100
typedef struct Node {
char text[MAX_LINE_LENGTH];
struct Node *yes;
struct Node *no;
} Node;
Node* create_node(const char* text) {
Node *node = (Node*)malloc(sizeof(Node));
if (!node) {
fprintf(stderr, "Memory allocation error.\n");
exit(1);
}
strncpy(node->text, text, MAX_LINE_LENGTH);
node->yes = NULL;
node->no = NULL;
return node;
}
Node* parse_knowledge_base(FILE *file) {
char line[MAX_LINE_LENGTH];
if (!fgets(line, sizeof(line), file) || line[0] == '\n') {
return NULL;
}
line[strcspn(line, "\n")] = 0; // Удалить символ новой строки
Node *node = NULL;
if (line[0] == '*') {
node = create_node(line + 1); // Создаём конечный узел (ответ)
} else {
node = create_node(line); // Создаём узел с вопросом
node->yes = parse_knowledge_base(file); // Рекурсивное создание поддерева для "да"
node->no = parse_knowledge_base(file); // Рекурсивное создание поддерева для "нет"
}
return node;
}
int count_products(Node *node) {
if (!node) return 0;
if (!node->yes && !node->no) return 1; // Если это ответ, возвращаем 1
return count_products(node->yes) + count_products(node->no);
}
void run_expert_system(Node *node, FILE *input) {
while (node) {
// Проверка, если это листовой узел (ответ)
if (!node->yes && !node->no) {
printf("*%s\n", node->text); // Выводим ответ с звездочкой
printf("Koniec\n");
return;
}
printf("Odpovedajte 'a' pre prvu moznost alebo 'n' pre druhu moznost.\n");
printf("%s\n", node->text);
char answer;
if (fscanf(input, " %c", &answer) != 1) {
printf("Koniec\n"); // Некорректный ввод
return;
}
// Переход по дереву на основе ответа
if (answer == 'a') {
node = node->yes;
} else if (answer == 'n') {
node = node->no;
} else {
printf("Koniec\n"); // Некорректный ввод
return;
}
}
}
void free_tree(Node *node) {
if (node) {
free_tree(node->yes);
free_tree(node->no);
free(node);
}
}
void create_default_knowledge_base() {
FILE *file = fopen("knowledge_base.txt", "w");
if (!file) {
perror("Failed to create the knowledge base file");
exit(1);
}
fprintf(file, "Je to ovocie alebo zelenina?\n");
fprintf(file, "*Jablko\n");
fprintf(file, "*Mrkva\n");
fprintf(file, "\n"); // Пустая строка для разделения базы знаний и ответов
fprintf(file, "a\n"); // Предустановленный ответ
fclose(file);
}
int main() {
FILE *file = fopen("knowledge_base.txt", "r");
if (!file) {
create_default_knowledge_base(); // Создаем файл по умолчанию
file = fopen("knowledge_base.txt", "r");
if (!file) {
perror("Failed to open the knowledge base file");
return 1; // Завершение с кодом ошибки, если файл так и не открылся
}
}
Node *root = parse_knowledge_base(file);
if (!root) {
printf("Báza znalostí sa nedá načítať.\n");
fclose(file);
return 1; // Завершение с кодом ошибки, если база знаний не загружена
}
printf("Expert z bufetu to vie.\n");
int product_count = count_products(root);
printf("Pozna %d druhov ovocia a zeleniny.\n", product_count);
// Пропуск пустой строки после базы знаний
char line[MAX_LINE_LENGTH];
while (fgets(line, sizeof(line), file) && line[0] != '\n');
run_expert_system(root, file); // Запуск системы с использованием оставшихся ответов
free_tree(root);
fclose(file);
return 0; // Успешное завершение программы
}