Update cv7/program.c
This commit is contained in:
		
							parent
							
								
									6f911eac8c
								
							
						
					
					
						commit
						9748e39462
					
				
							
								
								
									
										189
									
								
								cv7/program.c
									
									
									
									
									
								
							
							
						
						
									
										189
									
								
								cv7/program.c
									
									
									
									
									
								
							| @ -6,113 +6,144 @@ | ||||
| 
 | ||||
| // Структура вузла дерева
 | ||||
| struct TreeNode { | ||||
|     char *value;            // текст питання або відповіді
 | ||||
|     char value[SIZE];        // текст питання або відповіді
 | ||||
|     struct TreeNode *left;   // "так" гілка
 | ||||
|     struct TreeNode *right;  // "ні" гілка
 | ||||
| }; | ||||
| 
 | ||||
| // Функція для створення вузла дерева з текстом
 | ||||
| struct TreeNode* createNode(const char *text) { | ||||
|     struct TreeNode *node = (struct TreeNode*) malloc(sizeof(struct TreeNode)); | ||||
|     node->value = strdup(text); | ||||
| 
 | ||||
| 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; | ||||
| } | ||||
| 
 | ||||
| // Функція для завантаження бази знань у форматі pre-order
 | ||||
| struct TreeNode* loadTree(FILE *file) { | ||||
|     char buffer[SIZE]; | ||||
|     if (!fgets(buffer, SIZE, file) || buffer[0] == '\n') { | ||||
|         return NULL; | ||||
|     } | ||||
| 
 | ||||
|     // Створюємо вузол для поточного рядка
 | ||||
|     struct TreeNode *node = createNode(buffer); | ||||
| void read_code(char *code, int size, FILE *file) { | ||||
|     // Очищаємо буфер перед використанням
 | ||||
|     memset(code, 0, size); | ||||
| 
 | ||||
|     // Якщо це відповідь (починається з '*'), то повертаємо листовий вузол
 | ||||
|     if (buffer[0] == '*') { | ||||
|         return node; | ||||
|     } | ||||
| 
 | ||||
|     // Інакше рекурсивно завантажуємо лівий і правий нащадки
 | ||||
|     node->left = loadTree(file); | ||||
|     node->right = loadTree(file); | ||||
|     return node; | ||||
| } | ||||
| 
 | ||||
| // Рекурсивна функція для підрахунку товарів у базі знань
 | ||||
| int countItems(struct TreeNode *node) { | ||||
|     if (node == NULL) { | ||||
|         return 0; | ||||
|     } | ||||
|     if (node->left == NULL && node->right == NULL) { | ||||
|         return 1; // Листовий вузол є товаром
 | ||||
|     } | ||||
|     return countItems(node->left) + countItems(node->right); | ||||
| } | ||||
| 
 | ||||
| // Функція для запуску експертної системи з питаннями і відповідями
 | ||||
| void runExpertSystem(struct TreeNode *node) { | ||||
|     if (node == NULL) return; | ||||
| 
 | ||||
|     // Виводимо поточне питання або відповідь
 | ||||
|     printf("%s", node->value); | ||||
| 
 | ||||
|     // Якщо це листовий вузол, то закінчуємо роботу
 | ||||
|     if (node->left == NULL && node->right == NULL) { | ||||
|         printf("Koniec\n"); | ||||
|     // Зчитуємо код з файлу або stdin
 | ||||
|     if (fgets(code, size, file) == NULL) { | ||||
|         printf("Помилка: не вдалося зчитати код\n"); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     // Отримуємо відповідь користувача
 | ||||
|     char answer; | ||||
|     scanf(" %c", &answer);  // пробіл перед %c для пропуску зайвих пробілів
 | ||||
|     // Видаляємо символ нового рядка, якщо він є
 | ||||
|     code[strcspn(code, "\n")] = '\0'; | ||||
| } | ||||
| 
 | ||||
|     // Переходимо до відповідного нащадка
 | ||||
|     if (answer == 'a') { | ||||
|         runExpertSystem(node->left); | ||||
|     } else if (answer == 'n') { | ||||
|         runExpertSystem(node->right); | ||||
| 
 | ||||
| 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("Nerozumiem\n");  // Неправильна відповідь
 | ||||
|         printf("Помилка: код не веде до кінцевої відповіді\n"); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Функція для очищення пам'яті
 | ||||
| void freeTree(struct TreeNode *node) { | ||||
|     if (node == NULL) return; | ||||
|     freeTree(node->left); | ||||
|     freeTree(node->right); | ||||
|     free(node->value); | ||||
| 
 | ||||
| 
 | ||||
| void destroy_tree(struct TreeNode *node) { | ||||
|     if (node == NULL) { | ||||
|         return; // Якщо вузол порожній, просто повертаємося
 | ||||
|     } | ||||
| 
 | ||||
|     // Рекурсивно очищаємо ліве і праве піддерева
 | ||||
|     destroy_tree(node->left); | ||||
|     destroy_tree(node->right); | ||||
| 
 | ||||
|     // Звільняємо пам'ять для поточного вузла
 | ||||
|     free(node); | ||||
| } | ||||
| 
 | ||||
| int main() { | ||||
|     // Відкриваємо файл з базою знань
 | ||||
|     // В даному випадку, ми використовуємо stdin (вхід з консолі)
 | ||||
|     struct TreeNode *root = loadTree(stdin); | ||||
| 
 | ||||
|     // Перевірка наявності порожнього рядка після бази знань
 | ||||
|     if (root == NULL) { | ||||
|         printf("Помилка: База знань некоректна або пуста.\n"); | ||||
| int validate_code(const char *code) { | ||||
|     // Перевірка на довжину рядка
 | ||||
|     if (strlen(code) >= SIZE) { | ||||
|         printf("Помилка: код перевищує допустиму довжину\n"); | ||||
|         return 0; | ||||
|     } | ||||
| 
 | ||||
|     // Рахуємо кількість товарів і виводимо повідомлення
 | ||||
|     int itemCount = countItems(root); | ||||
|     printf("Expert z bufetu to vie.\n"); | ||||
|     printf("Pozna %d druhov ovocia a zeleniny.\n", itemCount); | ||||
|     printf("Odpovedajte 'a' pre prvu moznost alebo 'n' pre druhu moznost.\n"); | ||||
|     // Перевірка кожного символу
 | ||||
|     for (int i = 0; i < strlen(code); i++) { | ||||
|         if (code[i] != '0' && code[i] != '1') { | ||||
|             printf("Помилка: код містить некоректний символ '%c'\n", code[i]); | ||||
|             return 0; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // Запуск експертної системи
 | ||||
|     runExpertSystem(root); | ||||
|     return 1; // Код коректний
 | ||||
| } | ||||
| 
 | ||||
|     // Виведення повідомлення про завершення вводу
 | ||||
|     printf("Koniec vstupu\n"); | ||||
| 
 | ||||
|     // Звільняємо пам'ять
 | ||||
|     freeTree(root); | ||||
| 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; | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user