usaa24/cv7/program.c

150 lines
5.2 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 SIZE 256
// Структура вузла дерева
struct TreeNode {
char value[SIZE]; // текст питання або відповіді
struct TreeNode *left; // "так" гілка
struct TreeNode *right; // "ні" гілка
};
struct TreeNode *read_tree(FILE *file) {
char buffer[SIZE];
// Зчитуємо рядок тексту для поточного вузла
if (fgets(buffer, SIZE, file) == NULL) {
return NULL; // Кінець файлу або помилка читання
}
// Виділяємо пам'ять для нового вузла
struct TreeNode *node = (struct TreeNode *)malloc(sizeof(struct TreeNode));
if (node == NULL) {
perror("Не вдалося виділити пам'ять");
exit(EXIT_FAILURE);
}
// Копіюємо значення в новий вузол
strncpy(node->value, buffer, SIZE);
node->value[strcspn(node->value, "\n")] = '\0'; // Видаляємо символ нового рядка
node->left = NULL;
node->right = NULL;
// Перевіряємо, чи є вузол питанням (якщо починається з '#')
if (node->value[0] == '#') {
// Якщо це питання, рекурсивно зчитуємо ліве і праве піддерева
node->left = read_tree(file); // Піддерево для відповіді "так"
node->right = read_tree(file); // Піддерево для відповіді "ні"
}
// Повертаємо створений вузол (або лист, або вузол з піддеревами)
return node;
}
void read_code(char *code, int size, FILE *file) {
// Очищаємо буфер перед використанням
memset(code, 0, size);
// Зчитуємо код з файлу або stdin
if (fgets(code, size, file) == NULL) {
printf("Помилка: не вдалося зчитати код\n");
return;
}
// Видаляємо символ нового рядка, якщо він є
code[strcspn(code, "\n")] = '\0';
}
void traverse_tree(struct TreeNode *root, const char *code) {
struct TreeNode *current = root; // Починаємо з кореня дерева
for (int i = 0; i < strlen(code); i++) {
// Перевірка на символ "0" або "1"
if (code[i] == '0') {
current = current->left; // Переходимо вліво
} else if (code[i] == '1') {
current = current->right; // Переходимо вправо
} else {
printf("Помилка: код містить некоректний символ '%c'\n", code[i]);
return;
}
// Перевіряємо, чи не вийшли за межі дерева
if (current == NULL) {
printf("Помилка: шлях у коді виходить за межі дерева\n");
return;
}
}
// Виводимо результат, якщо досягли листа
if (current->left == NULL && current->right == NULL) {
printf("Відповідь: %s\n", current->value);
} else {
printf("Помилка: код не веде до кінцевої відповіді\n");
}
}
void destroy_tree(struct TreeNode *node) {
if (node == NULL) {
return; // Якщо вузол порожній, просто повертаємося
}
// Рекурсивно очищаємо ліве і праве піддерева
destroy_tree(node->left);
destroy_tree(node->right);
// Звільняємо пам'ять для поточного вузла
free(node);
}
int validate_code(const char *code) {
// Перевірка на довжину рядка
if (strlen(code) >= SIZE) {
printf("Помилка: код перевищує допустиму довжину\n");
return 0;
}
// Перевірка кожного символу
for (int i = 0; i < strlen(code); i++) {
if (code[i] != '0' && code[i] != '1') {
printf("Помилка: код містить некоректний символ '%c'\n", code[i]);
return 0;
}
}
return 1; // Код коректний
}
int main() {
// Зчитуємо дерево
struct TreeNode *root = read_tree(stdin);
// Зчитуємо код для навігації
char code[SIZE];
printf("Введіть код для навігації деревом: ");
read_code(code, SIZE, stdin);
// Перевірка коректності коду
if (!validate_code(code)) {
destroy_tree(root); // Очищення дерева перед завершенням програми
return 1; // Завершення програми через некоректний код
}
// Навігація деревом за допомогою коду та виведення результату
traverse_tree(root, code);
printf("\n");
// Очищення пам'яті, зайнятої деревом
destroy_tree(root);
return 0;
}