usaa24/cv7/program.c

146 lines
4.6 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_TEXT 256
// Структура вузла дерева
typedef struct Node {
char text[MAX_TEXT];
struct Node *yes;
struct Node *no;
} Node;
// Функція для створення нового вузла
Node* createNode(const char* text) {
Node* node = (Node*)malloc(sizeof(Node));
if (node) {
strncpy(node->text, text, MAX_TEXT);
node->yes = NULL;
node->no = NULL;
}
return node;
}
// Завантаження дерева з файлу
Node* loadTree(FILE *file) {
char line[MAX_TEXT];
if (!fgets(line, sizeof(line), file)) {
return NULL;
}
line[strcspn(line, "\n")] = 0; // Видаляємо новий рядок
// Визначаємо, чи це листовий вузол
if (line[0] == '*') {
return createNode(line + 1); // Видаляємо символ '*' на початку
}
// Створюємо внутрішній вузол з двома піддеревами
Node *node = createNode(line);
node->yes = loadTree(file);
node->no = loadTree(file);
return node;
}
// Функція для підрахунку вузлів (листових та внутрішніх)
void countNodes(Node* root, int* leafCount, int* internalCount) {
if (root == NULL) {
return;
}
if (root->yes == NULL && root->no == NULL) {
(*leafCount)++;
} else {
(*internalCount)++;
countNodes(root->yes, leafCount, internalCount);
countNodes(root->no, leafCount, internalCount);
}
}
// Функція для проведення діалогу з користувачем
void interact(Node* root) {
Node* current = root;
while (current->yes != NULL && current->no != NULL) {
printf("Odpovedajte 'a' pre prvu moznost alebo 'n' pre druhu moznost.\n");
printf("%s (a/n): ", current->text);
char answer;
// Читання одного символа для відповіді
int res = fgetc(stdin); // Використовуємо fgetc для точного контролю вводу
// Пропускаємо всі зайві символи нового рядка або пробіли
while (res == '\n' || res == ' ' || res == '\t') {
res = fgetc(stdin);
}
if (res == EOF) {
printf("Некоректна відповідь! Завершення програми.\n");
return;
}
answer = (char)res; // Зберігаємо введений символ
if (answer == 'a') {
current = current->yes;
} else if (answer == 'n') {
current = current->no;
} else {
printf("Некоректна відповідь! Завершення програми.\n");
return;
}
}
// Коли досягнуто листового вузла (товар)
printf("%s\n", current->text);
}
// Функція для очищення пам'яті дерева
void freeTree(Node* root) {
if (root == NULL) {
return;
}
freeTree(root->yes);
freeTree(root->no);
free(root);
}
int main(int argc, char *argv[]) {
// Відкриваємо файл або використовуємо стандартний вхід
FILE *file;
if (argc > 1) {
file = fopen(argv[1], "r");
if (!file) {
printf("Помилка: не вдалося відкрити файл %s.\n", argv[1]);
return 1;
}
} else {
file = stdin; // Використовуємо стандартний вхід, якщо файл не заданий
}
// Завантажуємо дерево з файлу
Node* root = loadTree(file);
if (file != stdin) fclose(file);
// Перевірка на успішне завантаження дерева
if (!root) {
printf("Помилка: дерево не було завантажене.\n");
return 1;
}
// Підрахунок вузлів
int leafCount = 0, internalCount = 0;
countNodes(root, &leafCount, &internalCount);
printf("Zasadny vykon\n");
printf("Zagolna kilkist tovariv (listovykh vuzliv): %d\n", leafCount);
printf("Kilkist pytan (vnutrishnikh vuzliv): %d\n", internalCount);
// Інтерактивна взаємодія з користувачем
printf("Pochynayemo dialoh...\n");
interact(root);
// Очищення пам'яті
freeTree(root);
printf("Program zaversheno uspishno.\n");
return 0;
}