Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<iostream>
- #include<fstream>
- #include<vector>
- #include<string>
- #include<regex>
- #include<thread>
- using namespace std;
- /****************************************************************************
- 1. SVE KLASE TREBAJU POSJEDOVATI ADEKVATAN DESTRUKTOR
- 2. NAMJERNO IZOSTAVLJANJE KOMPLETNIH I/ILI POJEDINIH DIJELOVA DESTRUKTORA KOJI UZROKUJU RUNTIME ERROR ĆE BITI OZNACENO KAO "RE"
- 3. SPAŠAVAJTE PROJEKAT KAKO BI SE SPRIJEČILO GUBLJENJE URAĐENOG ZADATKA
- 4. NAZIVI FUNKCIJA, TE BROJ I TIP PARAMETARA MORAJU BITI IDENTIČNI ONIMA KOJI SU KORIŠTENI U TESTNOM CODE-U, OSIM U SLUČAJU DA POSTOJI ADEKVATAN RAZLOG ZA NJIHOVU MODIFIKACIJU. OSTALE, POMOĆNE FUNKCIJE MOŽETE IMENOVATI I DODAVATI PO ŽELJI.
- 5. IZUZETAK BACITE U FUNKCIJAMA U KOJIMA JE TO NAZNAČENO.
- ****************************************************************************/
- const char* nedozvoljena_operacija = "Nedozvoljena operacija";
- const char* not_set = "NOT_SET";
- enum Sortiranje { ASC, DESC };
- enum Predmet { MATEMATIKA, FIZIKA, HEMIJA, GEOGRAFIJA, NOT_SET };
- enum Razred { I = 1, II, III, IV };
- string GetNazivPredmeta(Predmet p) {
- switch (p)
- {
- case MATEMATIKA:
- return "MATEMATIKA";
- case FIZIKA:
- return "FIZIKA";
- case HEMIJA:
- return "HEMIJA";
- case GEOGRAFIJA:
- return "GEOGRAFIJA";
- case NOT_SET:
- return "NOT_SET";
- default:
- return "";
- }
- }
- char* AlocirajNizKaraktera(const char* sadrzaj) {
- if (sadrzaj == nullptr)
- return nullptr;
- int vel = strlen(sadrzaj) + 1;
- char* temp = new char[vel];
- strcpy_s(temp, vel, sadrzaj);
- return temp;
- }
- template <class T1, class T2, int max>
- class Kolekcija {
- T1* _elementi1[max] = { nullptr };
- T2* _elementi2[max] = { nullptr };
- int _trenutnoElemenata;
- bool _dozvoliDupliranje;
- Sortiranje _sortiranje;
- public:
- Kolekcija(Sortiranje sortiranje = ASC, bool dozvoliDupliranje = true) {
- _trenutnoElemenata = 0;
- _sortiranje = sortiranje;
- _dozvoliDupliranje = dozvoliDupliranje;
- }
- Kolekcija(const Kolekcija& obj) {
- _trenutnoElemenata = obj._trenutnoElemenata;
- _dozvoliDupliranje = obj._dozvoliDupliranje;
- _sortiranje = obj._sortiranje;
- for (size_t i = 0; i < _trenutnoElemenata; i++)
- {
- _elementi1[i] = new T1(*obj._elementi1[i]);
- _elementi2[i] = new T2(*obj._elementi2[i]);
- }
- }
- Kolekcija& operator=(const Kolekcija& obj) {
- if (this == &obj)
- return *this;
- for (size_t i = 0; i < _trenutnoElemenata; i++)
- {
- delete _elementi1[i];
- delete _elementi2[i];
- _elementi1[i] = nullptr;
- _elementi2[i] = nullptr;
- }
- _trenutnoElemenata = obj._trenutnoElemenata;
- _dozvoliDupliranje = obj._dozvoliDupliranje;
- _sortiranje = obj._sortiranje;
- for (size_t i = 0; i < _trenutnoElemenata; i++)
- {
- _elementi1[i] = new T1(*obj._elementi1[i]);
- _elementi2[i] = new T2(*obj._elementi2[i]);
- }
- return *this;
- }
- ~Kolekcija() {
- for (size_t i = 0; i < _trenutnoElemenata; i++) {
- delete _elementi1[i]; _elementi1[i] = nullptr;
- delete _elementi2[i]; _elementi2[i] = nullptr;
- }
- }
- bool Sadrzi(T1 e1, T2 e2) {
- for (size_t i = 0; i < _trenutnoElemenata; i++)
- {
- if (*_elementi1[i] == e1 && *_elementi2[i] == e2)
- return true;
- }
- return false;
- }
- void Sortiraj() {
- int i, j, flag = 1; // set flag to 1 to start first pass
- T1* temp1;
- T2* temp2;
- for (i = 1; (i <= _trenutnoElemenata) && flag; i++)
- {
- flag = 0;
- for (j = 0; j < (_trenutnoElemenata - 1); j++)
- {
- if (_sortiranje == DESC) {
- if ((*_elementi1[j + 1]) > (*_elementi1[j]) ) // ascending order simply changes to <
- {
- temp1 = _elementi1[j]; // swap elements
- _elementi1[j] = _elementi1[j + 1];
- _elementi1[j + 1] = temp1;
- temp2 = _elementi2[j]; // swap elements
- _elementi2[j] = _elementi2[j + 1];
- _elementi2[j + 1] = temp2;
- flag = 1; // indicates that a swap occurred.
- }
- }
- else {
- if ((*_elementi1[j + 1]) < (*_elementi1[j]))
- {
- temp1 = _elementi1[j]; // swap elements
- _elementi1[j] = _elementi1[j + 1];
- _elementi1[j + 1] = temp1;
- temp2 = _elementi2[j]; // swap elements
- _elementi2[j] = _elementi2[j + 1];
- _elementi2[j + 1] = temp2;
- flag = 1; // indicates that a swap occurred.
- }
- }
- }
- }
- }
- void AddElement(T1 e1, T2 e2) {
- if (_trenutnoElemenata >= max)
- throw exception("Kolekcija je puna");
- if (!_dozvoliDupliranje && Sadrzi(e1, e2))
- throw exception("Kolekcija već sadrži elemente");
- _elementi1[_trenutnoElemenata] = new T1(e1);
- _elementi2[_trenutnoElemenata] = new T2(e2);
- _trenutnoElemenata++;
- Sortiraj();
- }
- int GetTrenutno() const { return _trenutnoElemenata; }
- int GetMax() const { return max; }
- T1& GetElement1(int lokacija) const {
- if (lokacija < 0 || lokacija >= _trenutnoElemenata)
- throw exception(nedozvoljena_operacija);
- return *_elementi1[lokacija];
- }
- T2& GetElement2(int lokacija) const {
- if (lokacija < 0 || lokacija >= _trenutnoElemenata)
- throw exception(nedozvoljena_operacija);
- return *_elementi2[lokacija];
- }
- void SetElement2(int lokacija, T2 ele2) {
- _elementi2[lokacija] = ele2;
- }
- friend ostream& operator<<(ostream& COUT, const Kolekcija& obj) {
- for (size_t i = 0; i < obj.GetTrenutno(); i++)
- COUT << obj.GetElement1(i) << " " << obj.GetElement2(i) << endl;
- return COUT;
- }
- };
- class Aktivnost {
- shared_ptr<Razred> _razred;
- string _opis;
- int _ocjena;//1-5
- public:
- Aktivnost(Razred razred = I, int ocjena = 0, string opis = not_set) {
- _ocjena = ocjena;
- _opis = opis;
- _razred = make_shared<Razred>(razred);
- }
- int GetOcjenu() const { return _ocjena; }
- string GetOpis() const { return _opis; }
- Razred GetRazred() const { return *_razred; }
- bool operator==(Aktivnost& obj) {
- return (*_razred) == *obj._razred && _ocjena == obj._ocjena && _opis == obj._opis;
- }
- bool operator>(Aktivnost& obj) {
- return *(obj._razred) > * _razred;
- }
- bool operator<(Aktivnost& obj) {
- return *(obj._razred) < *_razred;
- }
- friend ostream& operator<<(ostream& COUT, const Aktivnost& obj) {
- COUT << "Razred: " << *obj._razred << " Ocjena: " << obj._ocjena << " Opis:" << obj._opis << endl;
- return COUT;
- }
- bool JeIstiRazred(Aktivnost& a) {
- return (*_razred) == a.GetRazred();
- }
- };
- class Polaznik {
- protected:
- char* _imePrezime;
- string _brojTelefona;
- public:
- Polaznik(string imePrezime, string brojTelefona) :
- _imePrezime(AlocirajNizKaraktera(imePrezime.c_str())) {
- _brojTelefona = brojTelefona;
- }
- Polaznik(const Polaznik& obj) {
- _imePrezime = AlocirajNizKaraktera(obj._imePrezime);
- _brojTelefona = obj._brojTelefona;
- }
- Polaznik& operator=(const Polaznik& obj) {
- if (this == &obj)
- return *this;
- delete[]_imePrezime;
- _imePrezime = AlocirajNizKaraktera(obj._imePrezime);
- _brojTelefona = obj._brojTelefona;
- return *this;
- }
- ~Polaznik() { delete[] _imePrezime; }
- char* GetImePrezime() { return _imePrezime; }
- string GetTelefon() { return _brojTelefona; }
- virtual void PredstaviSe() = 0;
- };
- class Ucenik : public Polaznik {
- Kolekcija<Predmet, Aktivnost, 16> * _aktivnosti;
- public:
- Ucenik(string imePrezime, string brojTelefona) : Polaznik(imePrezime, brojTelefona) {
- _aktivnosti = new Kolekcija<Predmet, Aktivnost, 16>();
- }
- Ucenik(const Ucenik& obj) : Polaznik(obj) {
- _aktivnosti = new Kolekcija<Predmet, Aktivnost, 16>(*obj._aktivnosti);
- }
- Ucenik& operator=(const Ucenik& obj) {
- if (this == &obj)
- return *this;
- Polaznik::operator=(obj);
- *_aktivnosti = *obj._aktivnosti;
- Polaznik::operator=(obj);
- return *this;
- }
- int BrojAktivnostiURazredu(Razred r) {
- int ukupno = 0;
- for (size_t i = 0; i < _aktivnosti->GetTrenutno(); i++)
- {
- Razred razredAktivnost = _aktivnosti->GetElement2(i).GetRazred();
- if (razredAktivnost == r)
- ukupno++;
- }
- return ukupno;
- }
- float GetProsjek() {
- float suma = 0;
- int brojac = 0;
- for (size_t i = 0; i < _aktivnosti->GetTrenutno(); i++)
- {
- suma += _aktivnosti->GetElement2(i).GetOcjenu();
- brojac++;
- }
- if (brojac != 0)
- return suma / brojac;
- return suma;
- }
- bool ImaValidanBrojTelefona() {
- return _brojTelefona != not_set;
- }
- bool RazredSadrziAktivnostIzIstogPredmeta(Predmet p, Aktivnost a) {
- for (size_t i = 0; i < _aktivnosti->GetTrenutno(); i++)
- {
- Aktivnost aktivnost = _aktivnosti->GetElement2(i);
- Predmet predmet = _aktivnosti->GetElement1(i);
- if (aktivnost.JeIstiRazred(a) && predmet == p) {
- return true;
- }
- }
- return false;
- }
- void DodajAktivnost(Predmet p, Aktivnost a) {
- _aktivnosti->AddElement(p, a);
- }
- ~Ucenik() { delete _aktivnosti; _aktivnosti = nullptr; }
- void PredstaviSe() {
- cout << _imePrezime << " - " << _brojTelefona << endl;
- }
- Kolekcija<Predmet, Aktivnost, 16> & GetAktivnosti() { return *_aktivnosti; };
- friend ostream& operator<<(ostream& COUT, Ucenik& n)
- {
- COUT << n._imePrezime << " " << n._brojTelefona << endl;
- for (size_t i = 0; i < n._aktivnosti->GetTrenutno(); i++)
- {
- Predmet p = n._aktivnosti->GetElement1(i);
- Aktivnost a = n._aktivnosti->GetElement2(i);
- COUT << "Predmet " << GetNazivPredmeta(p) << endl;
- COUT << a << endl;
- }
- return COUT;
- }
- };
- void PosaljiSmsPoruku(string broj, float ocjena, Razred r) {
- cout << "Slanje SMS-a na broj " << broj << ": " << "Uspjesno ste okoncali aktivnosti u okviru " << r << " razreda sa prosjecnom ocjenom " << ocjena << endl;
- }
- class Skola {
- char* _naziv;
- vector<Ucenik> _ucenici;
- public:
- Skola(const char* naziv = nullptr) {
- _naziv = AlocirajNizKaraktera(naziv);
- }
- Skola(const Skola& obj) {
- _naziv = AlocirajNizKaraktera(obj._naziv);
- _ucenici = obj._ucenici;
- }
- Skola& operator=(const Skola& obj) {
- if (this == &obj)
- return *this;
- delete[] _naziv;
- _naziv = AlocirajNizKaraktera(obj._naziv);
- _ucenici = obj._ucenici;
- return *this;
- }
- ~Skola() {
- delete[] _naziv; _naziv = nullptr;
- }
- char* GetNaziv()const { return _naziv; }
- vector<Ucenik>& GetUcenici() { return _ucenici; };
- ///*U fajl (npr. Gimnazija.txt) upisati podatke (podatke upisati kao obicni tekst) o skoli i svim ucenicima.
- //Nakon upisa, potrebno je ispisati sadrzaj fajla. Parametar tipa bool oznacava da li ce ranije dodani sadrzaj fajla prethodno biti pobrisan*/
- bool SpasiUFajl(string nazivFajla, bool izbrisiPostojece = false) {
- ofstream mojFajl;
- if (izbrisiPostojece)
- mojFajl.open(nazivFajla, ios::out | ios::trunc );
- else
- mojFajl.open(nazivFajla, ios::out | ios::app);
- if (!mojFajl.is_open())
- return false;
- mojFajl << *this;
- mojFajl.close();
- }
- pair<Polaznik*, float> GetNajboljegUcenika() {
- float maxProsjek = 0;
- int lokMaxProsjeka = -1;
- for (size_t i = 0; i < _ucenici.size(); i++)
- {
- float tempProsjek = _ucenici[i].GetProsjek();
- if (tempProsjek > maxProsjek)
- {
- maxProsjek = tempProsjek;
- lokMaxProsjeka = i;
- }
- }
- if (lokMaxProsjeka == -1)
- throw exception("Lista učenika je prazna");
- Polaznik* p = &_ucenici[lokMaxProsjeka];
- return make_pair(p, maxProsjek);
- }
- Ucenik* GetUcenikByName(string ucenik) {
- for (size_t i = 0; i < _ucenici.size(); i++)
- {
- if (_ucenici[i].GetImePrezime() == ucenik)
- return &_ucenici[i];
- }
- return nullptr;
- }
- bool RazredVecSadrziAktivnostIzIstogPredmeta(Predmet predmet, Aktivnost aktivnost) {
- for (size_t i = 0; i < _ucenici.size(); i++)
- {
- if (_ucenici[i].RazredSadrziAktivnostIzIstogPredmeta(predmet, aktivnost))
- return true;
- }
- return false;
- }
- bool RazredImaPopunjeneAktivnosti(Razred r) {
- int ukupno = 0;
- for (size_t i = 0; i < _ucenici.size(); i++)
- {
- ukupno += _ucenici[i].BrojAktivnostiURazredu(r);
- if (ukupno >= 4)
- return true;
- }
- return false;
- }
- /*na nivou svakog razreda se mogu evidentirati maksimalno 4 aktivnosti, a takodjer,
- na nivou razreda se ne smiju ponavljati aktivnosti iz istog predmeta*/
- /*u slucaju da je ucenik uspjesno (ocjenom vecom od 1) realizovao aktivnosti na nivou odredjenog razreda, te posjeduje validan broj telefona,
- u okviru zasebnog thread-a se salje SMS sa sadrzajem "Uspjesno ste okoncali aktivnosti u okviru X razreda sa prosjecnom ocjenom X.X"*/
- bool DodajAktivnost(string imeUcenika, Predmet predmet, Aktivnost aktivnost) {
- if (RazredVecSadrziAktivnostIzIstogPredmeta(predmet, aktivnost))
- return false;
- if (RazredImaPopunjeneAktivnosti(aktivnost.GetRazred())) {
- return false;
- }
- Ucenik* ucenik = GetUcenikByName(imeUcenika);
- if (ucenik == nullptr)
- return false;
- try {
- ucenik->DodajAktivnost(predmet, aktivnost);
- if (aktivnost.GetOcjenu() > 1 && ucenik->ImaValidanBrojTelefona()) {
- thread t(PosaljiSmsPoruku, ucenik->GetTelefon(), aktivnost.GetOcjenu(), aktivnost.GetRazred());
- t.join();
- }
- return true;
- }
- catch (exception e) {
- return false;
- }
- }
- bool SadrziUcenika(string brojTelefona, string imePrezime) {
- for (size_t i = 0; i < _ucenici.size(); i++)
- {
- if (_ucenici[i].GetImePrezime() == imePrezime || _ucenici[i].GetTelefon() == brojTelefona)
- return true;
- }
- return false;
- }
- bool BrojTelefonaUIspravnomObliku(string broj) {
- //+387(6X)XXX - XXX ili +387 6X XXX - XXX
- regex praviloSaZagradama = regex("(\\+)(\\d{3})(\\()([6]\\d)(\\))(\\d{3})([-])(\\d{3})");
- regex praviloBezZagrada = regex("(\\+)(\\d{3})(\\s)([6]\\d)(\\s)(\\d{3})([-])(\\d{3})");
- if (regex_match(broj, praviloSaZagradama)) {
- return true;
- }
- else if (regex_match(broj, praviloBezZagrada)) {
- return true;
- }
- else {
- return false;
- }
- }
- //dodaje novog ucenika u skolu
- /*
- koristeci regex, osigurati sljedeci format za broj telefona: +387(6X)XXX-XXX ili +387 6X XXX-XXX
- onemoguciti pojavljivanje samo jedne zagrade, a ukoliko format nije adekvatna koristiti vrijednost not_set
- */
- /*onemoguciti dodavanje ucenika sa istim imenom i prezimenom ili brojem telefona*/
- void operator() (string ucenik, string brojTelefona) {
- if (SadrziUcenika(ucenik, brojTelefona))
- {
- throw exception("Ucenik je vec dodan");
- }
- if (!BrojTelefonaUIspravnomObliku(brojTelefona))
- brojTelefona = not_set;
- Ucenik noviUcenik = Ucenik(ucenik, brojTelefona);
- _ucenici.push_back(noviUcenik);
- }
- friend ostream& operator<<(ostream& COUT, Skola& obj) {
- COUT << "Skola: " << obj._naziv << endl;
- COUT << "Ucenici: " << endl;
- for (size_t i = 0; i < obj._ucenici.size(); i++)
- COUT << obj._ucenici[i] << endl;
- return COUT;
- }
- };
- int main() {
- Kolekcija<int, int, 10> kolekcija1(DESC, false);
- try {
- kolekcija1.AddElement(1, 2);
- //dupliranje elemenata nije dozvoljeno
- kolekcija1.AddElement(1, 2);
- }
- catch (exception& ex) {
- cout << ex.what();
- }
- /*nakon svakog dodavanja, elemente sortirati prema T1 i vrijednosti atributa _sortiranje*/
- for (size_t i = 1; i < kolekcija1.GetMax() - 1; i++)
- kolekcija1.AddElement(rand(), rand());
- cout << kolekcija1 << endl;
- try {
- //prekoracen maksimalan broj elemenata
- kolekcija1.AddElement(rand(), rand());
- }
- catch (exception& ex) {
- cout << ex.what();
- }
- cout << kolekcija1 << endl;
- Kolekcija<int, int, 10> kolekcija2(kolekcija1);
- cout << kolekcija2 << endl;
- Skola gimnazijaMostar("GIMNAZIJA MOSTAR");
- //dodaje novog ucenika u skolu
- gimnazijaMostar("Jasmin Azemovic", "+387(61)111-222");
- gimnazijaMostar("Adel Handzic", "+387(61)333-444");
- /*
- koristeci regex, osigurati sljedeci format za broj telefona: +387(6X)XXX-XXX ili +387 6X XXX-XXX
- onemoguciti pojavljivanje samo jedne zagrade, a ukoliko format nije adekvatna koristiti vrijednost not_set
- */
- gimnazijaMostar("Telefon NotValidFormat", "387 61)333-444");
- try
- {
- /*onemoguciti dodavanje ucenika sa istim imenom i prezimenom ili brojem telefona*/
- gimnazijaMostar("Adel Handzic", "+387(61)333-444");
- }
- catch (exception& ex)
- {
- cout << ex.what() << endl;
- }
- if (gimnazijaMostar.DodajAktivnost("Jasmin Azemovic", MATEMATIKA,
- Aktivnost(I, 4, "Priprema za takmicenje iz Matematije koje se odrzava u Konjicu 07.02.2019")))
- cout << "Aktivnost uspjesno dodana" << endl;
- /*na nivou svakog razreda se mogu evidentirati maksimalno 4 aktivnosti,
- a takodjer, na nivou razreda se ne smiju ponavljati aktivnosti iz istog predmeta*/
- if (!gimnazijaMostar.DodajAktivnost("Jasmin Azemovic", MATEMATIKA, Aktivnost(I, 4, "Aktivnosti iz matematike")))
- cout << "Aktivnost nije uspjesno dodana" << endl;
- if (gimnazijaMostar.DodajAktivnost("Jasmin Azemovic", FIZIKA, Aktivnost(I, 4, "Analiza stepena apsorpcije materijala ")))
- cout << "Aktivnost uspjesno dodana" << endl;
- /*u slucaju da je ucenik uspjesno (ocjenom vecom od 1) realizovao aktivnosti na nivou odredjenog razreda,
- te posjeduje validan broj telefona,
- u okviru zasebnog thread-a se salje SMS sa sadrzajem
- "Uspjesno ste okoncali aktivnosti u okviru X razreda sa prosjecnom ocjenom X.X"*/
- if (gimnazijaMostar.DodajAktivnost("Jasmin Azemovic", GEOGRAFIJA, Aktivnost(I, 4, "Izrada 5 reljefa Mostara")))
- cout << "Aktivnost uspjesno dodana" << endl;
- if (gimnazijaMostar.DodajAktivnost("Jasmin Azemovic", HEMIJA, Aktivnost(I, 4, "Izrada 5 reljefa Mostara")))
- cout << "Aktivnost uspjesno dodana" << endl;
- if (gimnazijaMostar.DodajAktivnost("Jasmin Azemovic", NOT_SET, Aktivnost(I, 4, "Izrada 5 reljefa Mostara")))
- cout << "Aktivnost uspjesno dodana" << endl;
- if (gimnazijaMostar.DodajAktivnost("Adel Handzic", MATEMATIKA, Aktivnost(II, 5, "Izrada skripte na temu integralni racun")))
- cout << "Aktivnost uspjesno dodana" << endl;
- //ispisuje sve ucenike i njihove aktivnosti
- cout << gimnazijaMostar << endl;
- pair<Polaznik*, float> par = gimnazijaMostar.GetNajboljegUcenika();
- cout << "Najbolji ucenik je " << par.first->GetImePrezime() << " sa prosjekom " << par.second << endl;
- /*U fajl (npr. Gimnazija.txt) upisati podatke (podatke upisati kao obicni tekst) o skoli i svim ucenicima.
- Nakon upisa, potrebno je ispisati sadrzaj fajla. Parametar tipa bool oznacava da li ce ranije dodani
- sadrzaj fajla prethodno biti pobrisan*/
- if (gimnazijaMostar.SpasiUFajl("Gimnazija.txt", true))
- cout << "Podaci o ucenicima uspjesno pohranjeni u fajl" << endl;
- if (gimnazijaMostar.SpasiUFajl("Gimnazija.txt", false))
- cout << "Podaci o ucenicima uspjesno pohranjeni u fajl" << endl;
- cin.get();
- system("pause>0");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement