diff --git a/cv7/program.c b/cv7/program.c index 61b3143..3dd3714 100644 --- a/cv7/program.c +++ b/cv7/program.c @@ -2,85 +2,151 @@ #include #include -typedef struct Uzol { +typedef struct Node { char *text; - struct Uzol *ano; - struct Uzol *nie; -} Uzol; + int is_answer; + struct Node *yes; + struct Node *no; +} Node; -int pocet_tovarov = 0; +char *read_line(void) { + size_t size = 100; + char *buffer = malloc(size); + if (!buffer) return NULL; -Uzol* vytvor_uzol(const char *text) { - Uzol *uzol = (Uzol *)malloc(sizeof(Uzol)); - uzol->text = strdup(text); - uzol->ano = NULL; - uzol->nie = NULL; - return uzol; -} - -Uzol* nacitaj_strom() { - char riadok[256]; - if (fgets(riadok, sizeof(riadok), stdin) == NULL || riadok[0] == '\n') { + int c; + size_t len = 0; + while ((c = getchar()) != EOF && c != '\n') { + if (len == size - 1) { + size *= 2; + char *new_buffer = realloc(buffer, size); + if (!new_buffer) { + free(buffer); + return NULL; + } + buffer = new_buffer; + } + buffer[len++] = c; + } + if (len == 0 && c == EOF) { + free(buffer); return NULL; } - riadok[strcspn(riadok, "\n")] = '\0'; - if (riadok[0] == '*') { - pocet_tovarov++; - return vytvor_uzol(riadok + 1); - } - Uzol *uzol = vytvor_uzol(riadok); - uzol->ano = nacitaj_strom(); - uzol->nie = nacitaj_strom(); - return uzol; + buffer[len] = '\0'; + return buffer; } -void vypis_otazku(Uzol *uzol) { - if (uzol == NULL) { - return; - } +int read_knowledge_base(char ***lines_ptr, int *num_lines) { + int capacity = 100; + char **lines = malloc(capacity * sizeof(char *)); + if (!lines) return -1; - printf("%s\n", uzol->text); - if (uzol->ano == NULL && uzol->nie == NULL) { - return; - } - - printf("Odpovedajte 'a' pre prvu moznost alebo 'n' pre druhu moznost.\n"); - - char odpoved; + int count = 0; while (1) { - odpoved = getchar(); // čítame odpoveď - while (getchar() != '\n'); // vyčistenie bufferu - if (odpoved == 'a' || odpoved == 'n') { - break; // Odpoveď je platná, ukončíme cyklus - } else { - printf("Nerozumiem\n"); - } - } + char *line = read_line(); + if (!line) break; - if (odpoved == 'a') { - if (uzol->ano != NULL) { - vypis_otazku(uzol->ano); - } - } else if (odpoved == 'n') { - if (uzol->nie != NULL) { - vypis_otazku(uzol->nie); + if (count == capacity) { + capacity *= 2; + char **new_lines = realloc(lines, capacity * sizeof(char *)); + if (!new_lines) { + for (int i = 0; i < count; i++) free(lines[i]); + free(lines); + return -1; + } + lines = new_lines; } + lines[count++] = line; } -} - -void spusti_system(Uzol *strom) { - printf("Expert z bufetu to vie.\n"); - printf("Pozna %d druhov ovocia a zeleniny.\n", pocet_tovarov); - vypis_otazku(strom); - printf("Koniec\n"); -} - -int main() { - Uzol *strom = nacitaj_strom(); - if (strom == NULL) { - printf("Chyba: Nepodarilo sa otvorit subor s pravidlami.\n"); - return 1; - } - spusti_system(strom); + *lines_ptr = lines; + *num_lines = count; return 0; } + +Node *build_tree(char **lines, int *index, int num_lines, int *count, int *error) { + if (*index >= num_lines) { + *error = 1; + return NULL; + } + + Node *node = malloc(sizeof(Node)); + if (!node) { + *error = 1; + return NULL; + } + + node->text = lines[(*index)++]; + node->yes = node->no = NULL; + node->is_answer = (node->text[0] == '*'); + + if (node->is_answer) { + (*count)++; + } else { + node->yes = build_tree(lines, index, num_lines, count, error); + node->no = build_tree(lines, index, num_lines, count, error); + } + return node; +} + +void run_knowledge_system(Node *root, int count) { + printf("Expert z bufetu to vie.\n"); + if (!root) { + printf("Chybna databaza\n"); + return; + } + + printf("Pozna %d druhov ovocia a zeleniny.\n", count); + printf("Odpovedajte 'a' pre prvu moznost alebo 'n' pre druhu moznost.\n"); + + Node *node = root; + while (node) { + printf("%s\n", node->text); + if (node->is_answer) { + printf("Koniec\n"); + return; + } + + char input[10]; + if (!fgets(input, sizeof(input), stdin)) { + printf("Koniec vstupu\n"); + return; + } + + input[strcspn(input, "\n")] = 0; + if (strcmp(input, "a") == 0) { + node = node->yes; + } else if (strcmp(input, "n") == 0) { + node = node->no; + } else { + printf("Nerozumiem\n"); + return; + } + } +} + +void free_tree(Node *node) { + if (!node) return; + if (!node->is_answer) { + free_tree(node->yes); + free_tree(node->no); + } + free(node); +} + +int main(void) { + char **lines; + int num_lines; + + if (read_knowledge_base(&lines, &num_lines) != 0 || num_lines == 0) { + printf("Expert z bufetu to vie.\n"); + printf("Chybna databaza\n"); + return 0; + } + + int index = 0, count = 0, error = 0; + Node *root = build_tree(lines, &index, num_lines, &count, &error); + + if (error || index != num_lines || count == 0) { + printf("Expert z bufetu to vie.\n"); + printf("Chybna databaza\n"); + for (int i = 0; i < num_lines; i++) free(lines[i]); \ No newline at end of file