usaa24/cv7/program.c
2024-11-08 14:33:17 +01:00

150 lines
3.7 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 validate_tree_structure(char lines[][MAX_LINE_LENGTH], int line_count) {
int leaf_count = 0;
int question_count = 0;
for (int i = 0; i < line_count; i++) {
if (lines[i][0] == '*') {
leaf_count++;
} else {
question_count++;
if (i + 2 < line_count && lines[i + 1][0] == '*' && lines[i + 2][0] == '*') {
i += 2; // Skip the two leaves as expected
} else if (i + 1 < line_count && lines[i + 1][0] != '*') {
return 0; // Обнаружена некорректная структура (более двух дочерних узлов у вопроса)
}
}
}
return question_count >= leaf_count;
}
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 first_question = 1;
while (node) {
if (first_question) {
printf("Odpovedajte 'a' pre prvu moznost alebo 'n' pre druhu moznost.\n");
first_question = 0;
}
if (!node->yes && !node->no) {
printf("*%s\n", node->text);
printf("Koniec\n");
return;
}
printf("%s\n", node->text);
char answer;
if (scanf(" %c", &answer) != 1) {
printf("Koniec vstupu\n");
return;
}
if (answer == 'a') {
node = node->yes;
} else if (answer == 'n') {
node = node->no;
} else {
printf("Nerozumiem\n");
return;
}
}
}
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++;
}
if (line_count == 0 || !validate_tree_structure(lines, line_count)) {
printf("Expert z bufetu to vie.\n");
printf("Chybna databaza\n");
return 0;
}
int index = 0;
Node *root = parse_knowledge_base(lines, &index, line_count);
if (!root) {
printf("Expert z bufetu to vie.\n");
printf("Chybna databaza\n");
return 0;
}
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;
}