Update cv7/program.c
This commit is contained in:
		
							parent
							
								
									65b986bded
								
							
						
					
					
						commit
						64afe397f6
					
				
							
								
								
									
										192
									
								
								cv7/program.c
									
									
									
									
									
								
							
							
						
						
									
										192
									
								
								cv7/program.c
									
									
									
									
									
								
							| @ -2,121 +2,139 @@ | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| 
 | ||||
| #define SIZE 256 | ||||
| #define MAX_TEXT 256 | ||||
| 
 | ||||
| // Структура вузла дерева
 | ||||
| struct TreeNode { | ||||
|     char *value;            // текст питання або відповіді
 | ||||
|     struct TreeNode *left;   // "так" гілка
 | ||||
|     struct TreeNode *right;  // "ні" гілка
 | ||||
| }; | ||||
| typedef struct Node { | ||||
|     char text[MAX_TEXT]; | ||||
|     struct Node *yes; | ||||
|     struct Node *no; | ||||
| } Node; | ||||
| 
 | ||||
| // Функція для створення вузла дерева з текстом
 | ||||
| struct TreeNode* createNode(const char *text) { | ||||
|     struct TreeNode *node = (struct TreeNode*) malloc(sizeof(struct TreeNode)); | ||||
|     node->value = strdup(text); | ||||
|     node->left = NULL; | ||||
|     node->right = NULL; | ||||
| // Функція для створення нового вузла
 | ||||
| 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; | ||||
| } | ||||
| 
 | ||||
| // Функція для завантаження бази знань у форматі pre-order
 | ||||
| struct TreeNode* loadTree(FILE *file) { | ||||
|     char buffer[SIZE]; | ||||
|     if (!fgets(buffer, SIZE, file) || buffer[0] == '\n') { | ||||
| // Завантаження дерева з файлу
 | ||||
| Node* loadTree(FILE *file) { | ||||
|     char line[MAX_TEXT]; | ||||
|     if (!fgets(line, sizeof(line), file)) { | ||||
|         return NULL; | ||||
|     } | ||||
|     line[strcspn(line, "\n")] = 0;  // Видаляємо новий рядок
 | ||||
| 
 | ||||
|     // Створюємо вузол для поточного рядка
 | ||||
|     struct TreeNode *node = createNode(buffer); | ||||
| 
 | ||||
|     // Якщо це відповідь (починається з '*'), то повертаємо листовий вузол
 | ||||
|     if (buffer[0] == '*') { | ||||
|         return node; | ||||
|     // Визначаємо, чи це листовий вузол
 | ||||
|     if (line[0] == '*') { | ||||
|         return createNode(line + 1);  // Видаляємо символ '*' на початку
 | ||||
|     } | ||||
| 
 | ||||
|     // Інакше рекурсивно завантажуємо лівий і правий нащадки
 | ||||
|     node->left = loadTree(file); | ||||
|     node->right = loadTree(file); | ||||
|     // Створюємо внутрішній вузол з двома піддеревами
 | ||||
|     Node *node = createNode(line); | ||||
|     node->yes = loadTree(file); | ||||
|     node->no = 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"); | ||||
| // Функція для підрахунку вузлів (листових та внутрішніх)
 | ||||
| void countNodes(Node* root, int* leafCount, int* internalCount) { | ||||
|     if (root == NULL) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     // Отримуємо відповідь користувача
 | ||||
|     char answer; | ||||
|     scanf(" %c", &answer); | ||||
| 
 | ||||
|     // Переходимо до відповідного нащадка
 | ||||
|     if (answer == 'a') { | ||||
|         runExpertSystem(node->left); | ||||
|     } else if (answer == 'n') { | ||||
|         runExpertSystem(node->right); | ||||
|     if (root->yes == NULL && root->no == NULL) { | ||||
|         (*leafCount)++; | ||||
|     } else { | ||||
|         printf("Nerozumiem\n"); | ||||
|         (*internalCount)++; | ||||
|         countNodes(root->yes, leafCount, internalCount); | ||||
|         countNodes(root->no, leafCount, internalCount); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Функція для очищення пам'яті
 | ||||
| void freeTree(struct TreeNode *node) { | ||||
|     if (node == NULL) return; | ||||
|     freeTree(node->left); | ||||
|     freeTree(node->right); | ||||
|     free(node->value); | ||||
|     free(node); | ||||
| // Функція для проведення діалогу з користувачем
 | ||||
| void interact(Node* root) { | ||||
|     Node* current = root; | ||||
|     while (current->yes != NULL && current->no != NULL) { | ||||
|         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); | ||||
| } | ||||
| 
 | ||||
| int main() { | ||||
|     // Відкриваємо файл з базою знань
 | ||||
|   //  FILE *file = fopen("baza.txt", "r");
 | ||||
|   //  if (file == NULL) {
 | ||||
|   //      printf("Nepodarilo sa otvoriť súbor databázy znalostí.\n");
 | ||||
|  //       return 0;
 | ||||
|  //   }
 | ||||
| 
 | ||||
|     // Завантажуємо базу знань в дерево
 | ||||
|     struct TreeNode *root = loadTree(stdin); | ||||
|   //  fclose(file);
 | ||||
| 
 | ||||
|     // Перевірка наявності порожнього рядка після бази знань
 | ||||
| // Функція для очищення пам'яті дерева
 | ||||
| void freeTree(Node* root) { | ||||
|     if (root == NULL) { | ||||
|         printf("Помилка: База знань некоректна або пуста.\n"); | ||||
|         return 0; | ||||
|         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;  // Використовуємо стандартний вхід, якщо файл не заданий
 | ||||
|     } | ||||
| 
 | ||||
|     // Рахуємо кількість товарів і виводимо повідомлення
 | ||||
|     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"); | ||||
|     // Завантажуємо дерево з файлу
 | ||||
|     Node* root = loadTree(file); | ||||
|     if (file != stdin) fclose(file); | ||||
| 
 | ||||
|     // Запуск експертної системи
 | ||||
|     runExpertSystem(root); | ||||
|     // Перевірка на успішне завантаження дерева
 | ||||
|     if (!root) { | ||||
|         printf("Помилка: дерево не було завантажене.\n"); | ||||
|         return 1; | ||||
|     } | ||||
| 
 | ||||
|     // Звільняємо пам'ять
 | ||||
|     // Підрахунок вузлів
 | ||||
|     int leafCount = 0, internalCount = 0; | ||||
|     countNodes(root, &leafCount, &internalCount); | ||||
|     printf("Загальна кількість товарів (листових вузлів): %d\n", leafCount); | ||||
|     printf("Кількість питань (внутрішніх вузлів): %d\n", internalCount); | ||||
| 
 | ||||
|     // Інтерактивна взаємодія з користувачем
 | ||||
|     printf("Починаємо діалог...\n"); | ||||
|     interact(root); | ||||
| 
 | ||||
|     // Очищення пам'яті
 | ||||
|     freeTree(root); | ||||
|     printf("Програма завершена успішно.\n"); | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user