#include #include #include #include #include #include #define BRACKETS_NUM 100 // struktura pre spojkovany zoznam typedef struct Node{ char data; struct Node* next; } LinkedNode; // funkcia na vytrovorenie LinkedNode* createNode(char data){ //dynamicke allokujeme node v pamati pomocou mallalocu. Allokujeme v heape; rozdiel medzi mallocom a callacom v tom, ze ne bity neinitializovane LinkedNode* node = (LinkedNode*)malloc(sizeof(LinkedNode)); //pridame nejaky char informacii v node spojkovaneho zoznamu node->data = data; // pointer na nasledujuci node je null, cize nic node->next = NULL; // vratime node return node; } // pracujeme s refenciou na referenciu, pretoze mozet potrebovat zmenit hodnotu referencii /// funkcia pre pridanie nodu na konied; void push(LinkedNode** head, char data){ // ked' hodnota prveho nodu je NULL, vytvorime novy nod, pridame prvemu ho ako hodnotu a zrusime program if(*head == NULL){ LinkedNode* node = createNode(data); *head = node; return; } //ideme na koniec spojkovaneho zoznamu pomocou while; pomocou * berieme hodnotu LinkedNode* cur = *head; while(cur->next){ cur = cur->next; } // u posledneho nodu pridame novy pomocou funckcii cur->next = createNode(data); } // funkcia pre porovnanie zatvoriek; bool compare(char data1, char data2){ if(data1 == '(' && data2 == ')'){ return true; } else if(data1 == '<' && data2 == '>'){ return true; } else if (data1 == '[' && data2 == ']'){ return true; } else if (data1 == '{' && data2 == '}'){ return true; } return false; } // funkcia pre dostavanie hodnoty char nodu od konca; pracujeme z spjkovanym zoznamom ako keby zo stackom char pop(LinkedNode** head){ // mame pointer na predchadzajuci nod ako NULL na zaciatku a pointer na prvy nod LinkedNode* prev = NULL; LinkedNode* ptr = *head; // pokial refencia v pamati an nasledujuci nie je NULL - ideme na koniec; pri tom, ukladajeme informaciou o predchadzajuecem v prev while (ptr->next) { prev = ptr; ptr = ptr->next; } // informacia v poslednem node char res = ptr->data; if(prev){ // ak v spajkovanom zozname ne len prvy nod, tak vynulujeme poslednej prev->next = NULL;} else{ //inak v zozname len hlava - vynulujeme ju *head = NULL; } // potrebujeme vyvolnyt pointer aby nebolo nejaky memory leak free(ptr); // vratim hodnotu posledneho nodu return res; } // funkcia pre nacitanie vstupu; ma ako parameter void read_input(LinkedNode** head){ // buffer pre nacitnie zo standartneho vstupu char buff[BRACKETS_NUM]; /// nacitujeme zo standartneho vstupu fgets(buff, BRACKETS_NUM, stdin); // index pre iterovanie int i =0; // pokial nacitane nie je null while (buff[i]) { //mozeme kludne ignorovat' vsetky symboly, ktory nie su zatvorky // ked' je to otvoraca zatvorka - pridame ju do zasobniku if(buff[i] == '[' || buff[i] == '<' || buff[i] == '{' || buff[i] == '('){ push(head, buff[i]);} // ked' je to zatvoraca zatvvorka tak, porovnajeme ju pomocou funkcii ak nieco v zsaobniku je if(buff[i] == '>' || buff[i] == '}' || buff[i] == ']' || buff[i] == ')'){ // ak prvy nod je NULL, tak "stack" je przadny; nemozeme urobit' nic a vypiseme chybovu hlasku, zrusim program if(*head == NULL){ printf("Read: %sUnexpected closing bracket %c in %d\n", buff, buff[i], i); return; } //dostaneme otvorku zo stacku char popped = pop(head); // ak nie je to spravny typ, tak vypiseme chybovu hlasku podl'a podmienok: aky symbol nie je sprany, kde a co ocakovame if (!compare(popped, buff[i])) { if (popped == '[' && buff[i] == '>') { printf("Read: %s", buff); printf("Crossed bracket %c", buff[i]); printf(" in %d,", i); printf(" expected ] \n"); return; } if (popped == '(' && buff[i] == '>') { printf("Read: %s", buff); printf("Crossed bracket %c", buff[i]); printf(" in %d,", i); printf(" expected ) \n"); return; } if (popped == '{' && buff[i] == '>') { printf("Read: %s", buff); printf("Crossed bracket %c", buff[i]); printf(" in %d,", i); printf(" expected }\n"); return; } if (popped == '<' && buff[i] == ']') { printf("Read: %s", buff); printf("Crossed bracket %c", buff[i]); printf(" in %d,", i); printf(" expected > \n"); return; } if (popped == '(' && buff[i] == ']') { printf("Read: %s", buff); printf("Crossed bracket %c", buff[i]); printf(" in %d,", i); printf(" expected ) \n"); return; } if (popped == '{' && buff[i] == ']') { printf("Read: %s", buff); printf("Crossed bracket %c", buff[i]); printf(" in %d,", i); printf(" expected } \n"); return; } if (popped == '<' && buff[i] == ')') { printf("Read: %s", buff); printf("Crossed bracket %c", buff[i]); printf(" in %d,", i); printf(" expected > \n"); return; } if (popped == '[' && buff[i] == ')') { printf("Read: %s", buff); printf("Crossed bracket %c", buff[i]); printf(" in %d,", i); printf(" expected ] \n"); return; } if (popped == '{' && buff[i] == ')') { printf("Read: %s", buff); printf("Crossed bracket %c", buff[i]); printf(" in %d,", i); printf(" expected } \n"); return; } if (popped == '<' && buff[i] == '}') { printf("Read: %s", buff); printf("Crossed bracket %c", buff[i]); printf(" in %d,", i); printf(" expected > \n"); return; } if (popped == '(' && buff[i] == '}') { printf("Read: %s", buff); printf("Crossed bracket %c", buff[i]); printf(" in %d,", i); printf(" expected ) \n"); return; } if (popped == '[' && buff[i] == '}') { printf("Read: %s", buff); printf("Crossed bracket %c", buff[i]); printf(" in %d,", i); printf(" expected ] \n"); return; } } } i++; } // ak prvy node, hlava, nie je NULL, tak to zmanema ze nejaka otrvoraca uz nenasla zatvoracu zatvorku if(*head != NULL){ // vypiseme chybovu hlasku, a ptom zaciname dostavat' hodnotu od konca printf("Read: %sMissing closing brackets: ", buff); LinkedNode* ptr = *head; // pokial v "stacku" nieco je while(ptr){ char popped = pop(&ptr); // v zavislosti od typu zatvorky pridame prislusnu zatvoracu zatvorku d chybovu hlasku do standartneho vystupu pomocou putchar if(popped == '['){ putchar(']'); } if(popped== '('){ putchar(')'); } if(popped == '{'){ putchar('}'); } if(popped == '<'){ putchar('>'); } } putchar('\n'); return; } /// ak vsetko je spravne - vypiseme to printf("Read: %sAll brackets OK\n", buff); } int main(void){ // zaciname od nuly, "stack" je prazdny na zaciatku LinkedNode* head = NULL; read_input(&head); return 0; }