usaa24/cv7/program.c
2024-11-08 13:55:47 +01:00

131 lines
3.9 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, "Ошибка выделения памяти.\n");
exit(1);
}
strncpy(node->text, text, MAX_LINE_LENGTH);
node->yes = NULL;
node->no = NULL;
return node;
}
// Рекурсивно создает дерево из базы знаний, хранящейся в массиве строк
Node* parse_knowledge_base(char lines[][MAX_LINE_LENGTH], int *index, int line_count) {
if (*index >= line_count || lines[*index][0] == '\0') {
return NULL;
}
char *line = lines[*index];
(*index)++; // Переход к следующей строке
Node *node = NULL;
if (line[0] == '*') {
node = create_node(line + 1); // Узел с ответом
} else {
node = create_node(line); // Узел с вопросом
node->yes = parse_knowledge_base(lines, index, line_count); // Ветка "да"
node->no = parse_knowledge_base(lines, index, line_count); // Ветка "нет"
}
return node;
}
// Подсчитывает количество конечных узлов (продуктов) в дереве
int count_products(Node *node) {
if (!node) return 0;
if (!node->yes && !node->no) return 1; // Листовой узел - это продукт
return count_products(node->yes) + count_products(node->no);
}
// Запускает систему, задавая вопросы и ожидая ответы
void run_expert_system(Node *node) {
int end_input = 0; // Флаг, чтобы отметить "Koniec vstupu" только в нужных случаях
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 (scanf(" %c", &answer) != 1) {
end_input = 1; // Устанавливаем флаг для "Koniec vstupu"
break;
}
if (answer == 'a') {
node = node->yes;
} else if (answer == 'n') {
node = node->no;
} else {
printf("Nerozumiem\n");
return;
}
}
if (end_input) {
printf("Koniec vstupu\n");
}
}
// Освобождает выделенную память для дерева
void free_tree(Node *node) {
if (node) {
free_tree(node->yes);
free_tree(node->no);
free(node);
}
}
int main() {
char lines[100][MAX_LINE_LENGTH];
int line_count = 0;
// Считываем базу знаний построчно
while (fgets(lines[line_count], sizeof(lines[line_count]), stdin)) {
lines[line_count][strcspn(lines[line_count], "\n")] = 0; // Удаляем символ новой строки
if (lines[line_count][0] == '\0') { // Пустая строка завершает ввод базы знаний
break;
}
line_count++;
}
// Создаем дерево из базы знаний
int index = 0;
Node *root = parse_knowledge_base(lines, &index, line_count);
if (!root) {
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);
// Запуск опроса пользователя
run_expert_system(root);
// Очистка памяти
free_tree(root);
return 0;
}