#include #include using namespace std; // jedan element steka class element { // zarad direktnog pristupa vrednostima steka od strane klase verificator friend class verificator; char x; // simbol zagrade element *next; // polazivac na sledeci element public: element(char x,element*next=0): x(x),next(next) {} }; class verificator { bool noerror; // indikator validnosti string le; // string za poruku o gresci element *top; // vrh steka // dva stringa koji sadrze simbole zagrada static const char opening[]; static const char closing[]; static const int nsmb; // duzina ova dva stringa public: // na pocetku je indikator validnosti true // a pokazivac na vrh steka null verificator(): noerror(true),top(0) {} // po zavrsetku treba pocistiti ~verificator() { clear(); } void push(char); // ubacivanje novog elementa char pop(); // izbacivanje elementa sa vrha steka void clear(); // ciscenje i reinicijalizovanje objekta bool valid() // da li je bilo krsenja pravila do sada? { return noerror; } bool empty() // da li je stek prazan? { return !top; } // da li je prosledjeni znak jedan od znakova koji oznacava // zatvaranje zagrade? bool isclosing(char x) const { return position(x,closing) < nsmb; } // da li je prosledjeni znak jedan od znakova koji oznacava // otvaranje zagrade? bool isopening(char x) const { return position(x,opening) < nsmb; } // pozicija prvog nadjenog simbola jednakog prosledjenog // simbolu u prosledjenom stringu int position(char,const char*) const; // da li dva simbola, za otvaranje i zatvaranje zagrade, // odgovaraju jedan drugom bool match(char o,char c) { return c == closing[position(o,opening)]; } // vraca kopiju stringa koji nosi poruku o poslednjoj gresci. string lasterror() { return le; } }; /* ova dva stringa definisu simbole koji predstavljaju otvaranja i zatvaranja zagrada. simboli prvog i drugog stringa sa istim indeksima odgovaraju jedan drugom. zagrade koje su blize pocetku stringa imaju veci prioritet od ohin koje su dalje od pocetka stringa, */ const char verificator::opening[] = "([{"; const char verificator::closing[] = ")]}"; const int verificator::nsmb = strlen(opening); main() { verificator v; char c; // unos sa tastature. na isti nacin se moze citati // string iz njega unositi znak-po-znak while(true) { c = cin.get(); if(c=='\n' || !cin) break; v.push(c); } // proces provere je zavrsen. sledi predstavljanje rezultata if(!v.valid()) { cout << v.lasterror() << endl; } else if(!v.empty()) { cout << "Nisu sve zagrade zatvorene!\n"; } else { cout << "Just like king's tear.\n"; } return 0; } void verificator::push(char x) { if(isopening(x)) // ako se radi o otvaranju zagrade { // moguce greske if(top && (position(x,opening) > position(top->x,opening))) { le = "Otvaranje zagrade manjeg unutar zagrade viseg prioriteta."; noerror = false; } else { // dodavanje novog elementa top = new element(x,top); } } else if(isclosing(x)) // ako se radi o zatvaranju zagrade { if(top && match(top->x,x)) // ukoliko je sve u redu... { // ... brise se element sa vrha steka pop(); } else { // u suprotnom se prijavljuju odgovarajuce greske le = top? "Suvisno/prevremeno zatvaranje zagrade!": "Zatvaranje zagrade koja nije prethodno otvorena!"; noerror = false; } } // ostali simboli ce biti ignorisani } char verificator::pop() { char res=0; if(top) { element *e; res = top->x; e = top; top = top->next; delete e; } return res; } void verificator::clear() { element *e; while(top) { e = top; top = top->next; delete e; } noerror = true; } int verificator::position(char o,const char*s) const { int i; for(i=0;i