Advertisement
limun11

grupa b detaljno

Jul 5th, 2017
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 16.41 KB | None | 0 0
  1. #include<iostream>
  2. #include<cstring>
  3. #include<memory> //potrebno za pametne pokazivace
  4. #include<functional> //ptrebno za "auto" kod lambda funckije
  5. using namespace std;
  6.  
  7. #pragma warning(disable:4996)
  8. char *crt = "\n-------------------------------------------\n";
  9.  
  10. enum eNacinStudiranja { REDOVAN, DL };
  11. enum eRazred { PRVI = 1, DRUGI, TRECI, CETVRTI };
  12.  
  13. struct DatumVrijeme {
  14.     int *_dan, *_mjesec, *_godina, *_sati, *_minuti;
  15.     void Unos(int dan = 1, int mjesec = 1, int godina = 2000, int sati = 0, int minuti = 0) {
  16.         _dan = new int(dan);
  17.         _mjesec = new int(mjesec);
  18.         _godina = new int(godina);
  19.         _sati = new int(sati);
  20.         _minuti = new int(minuti);
  21.     }
  22.     void Dealociraj() {
  23.         delete _dan; _dan = nullptr;
  24.         delete _mjesec; _mjesec = nullptr;
  25.         delete _godina; _godina = nullptr;
  26.         delete _sati; _sati = nullptr;
  27.         delete _minuti; _minuti = nullptr;
  28.     }
  29.     void Ispis() {
  30.         cout << *_dan << "." << *_mjesec << "." << *_godina << " " << *_sati << ":" << *_minuti << endl;
  31.     }
  32.  
  33.     char* GetDatumKaoNizKaraktera() {
  34.  
  35.         int duzinaDan = 0, duzinaMjesec = 0, duzinaGodina = 0, duzinaSati = 0, duzinaMinuti = 0;
  36.         int tacka = 1, razmak = 1, dvotacka = 1, terminirajucaNula = 1; //duzine su nam potrebne da znamo velicinu char niza kojeg moramo alocirati
  37.  
  38.         //trazimo duzinu (broj cifara) svakog broja
  39.         int pom = *_dan;
  40.         while (pom) {
  41.             duzinaDan++;
  42.             pom /= 10;
  43.         }
  44.         pom = *_mjesec;
  45.         while (pom) {
  46.             duzinaMjesec++;
  47.             pom /= 10;
  48.         }
  49.         pom = *_godina;
  50.         while (pom) {
  51.             duzinaGodina++;
  52.             pom /= 10;
  53.         }
  54.         pom = *_sati;
  55.         while (pom) {
  56.             duzinaSati++;
  57.             pom /= 10;
  58.         }
  59.         pom = *_minuti;
  60.         while (pom) {
  61.             duzinaMinuti++;
  62.             pom /= 10;
  63.         }
  64.  
  65.         //smjestamo dan, mjesec i godinu u char niz, int pretvaramo u char[] _itoa_s funkcijom
  66.         //velicine nizova moraju biti za jedan vece zbog \0
  67.         char charDan[3], charMjesec[3], charGodina[5], charSati[3], charMinuti[3];
  68.         _itoa_s(*_dan, charDan, 3, 10); //broj koji zelimo staviti u charNiz, mjesto gdje stavljamo broj, velicina char niza gdje stavljamo, brojni sistem u koji pretvaramo
  69.         _itoa_s(*_mjesec, charMjesec, 3, 10);
  70.         _itoa_s(*_godina, charGodina, 5, 10);
  71.  
  72.         if (duzinaSati == 2) _itoa_s(*_sati, charSati, 3, 10); //ako je sat sastavljen od dvije cifre, samo taj broj pretvorimo u char niz
  73.         else { //ako nije
  74.             _itoa_s(0, charSati, 3, 10); //u char sate prvo stavljamo nulu
  75.             char pom[2]; //pravimo pomocin char niz u kojeg cemo smjestiti samo tu jenu cifru sati
  76.             _itoa_s(*_sati, pom, 2, 10); //pretvaramo tu cifru u char i stavaljamo u pomocni char niz
  77.             strcat_s(charSati, 3, pom); //i dodajemo je na nulu
  78.         }
  79.  
  80.         //identicno radimo za minute
  81.         if (duzinaMinuti == 2) _itoa_s(*_minuti, charMinuti, 3, 10);
  82.         else {
  83.             _itoa_s(0, charMinuti, 3, 10);
  84.             char pom[2];
  85.             _itoa_s(*_minuti, pom, 2, 10);
  86.             strcat_s(charMinuti, 3, pom);
  87.         }
  88.        
  89.         int velicina = duzinaDan + tacka + duzinaMjesec + tacka + duzinaGodina + razmak + duzinaSati + dvotacka + duzinaMinuti + terminirajucaNula;
  90.         char* niz = new char[velicina]; //alociramo niz velicine koju smo sracunali
  91.         strcpy_s(niz, velicina, charDan); //kopiramo dan, te dodajemo tacke, brojeve i razmake itd da kreiramo konazni niz
  92.         strcat_s(niz, velicina, ".");
  93.         strcat_s(niz, velicina, charMjesec);
  94.         strcat_s(niz, velicina, ".");
  95.         strcat_s(niz, velicina, charGodina);
  96.         strcat_s(niz, velicina, " ");
  97.         strcat_s(niz, velicina, charSati);
  98.         strcat_s(niz, velicina, ":");
  99.         strcat_s(niz, velicina, charMinuti);
  100.         return niz;
  101.     }
  102.  
  103.  
  104. };
  105. const DatumVrijeme rokZaPrijavu = { new int(5), new int(7), new int(2017), new int(12), new int(30) };
  106.  
  107. struct Predmet {
  108.     char * _naziv;
  109.     int _ocjena;
  110.     DatumVrijeme * _datumUnosa;
  111.     void Unos(char * naziv, int ocjena, DatumVrijeme datumUnosa) {
  112.         int vel = strlen(naziv) + 1;
  113.         _naziv = new char[vel];
  114.         strcpy_s(_naziv, vel, naziv);
  115.         _ocjena = ocjena;
  116.         _datumUnosa = new DatumVrijeme;
  117.         _datumUnosa->Unos(*datumUnosa._dan, *datumUnosa._mjesec, *datumUnosa._godina, *datumUnosa._sati, *datumUnosa._minuti);
  118.     }
  119.     void Dealociraj() {
  120.         delete[] _naziv; _naziv = nullptr;
  121.         _datumUnosa->Dealociraj(); delete _datumUnosa; _datumUnosa = nullptr;
  122.     }
  123.  
  124.     void Ispis() {
  125.         //kreirati funkciju GetDatumKaoNizKaraktera() koja vraca vrijednosti atributa strukture datum kao niz karaktera
  126.         cout << _naziv << " (" << _ocjena << ") "<< _datumUnosa->GetDatumKaoNizKaraktera() << endl;
  127.     }
  128. };
  129.  
  130. struct Uspjeh {
  131.     eRazred _razred;
  132.     Predmet * _predmeti;
  133.     int _brojPredmeta;
  134.     void Unos(eRazred razred) {
  135.         _razred = razred;
  136.         _predmeti = nullptr;
  137.         _brojPredmeta = 0;
  138.     }
  139.     void Dealociraj() {
  140.         for (int i = 0; i < _brojPredmeta; i++)
  141.             _predmeti[i].Dealociraj();
  142.         delete[] _predmeti; _predmeti = nullptr;
  143.     }
  144.  
  145.     void Ispis() {
  146.         cout << crt << "Razred -> " << _razred << crt;
  147.         for (int i = 0; i < _brojPredmeta; i++)
  148.             _predmeti[i].Ispis();
  149.     }
  150.  
  151.     void DodajPredmet(Predmet predmet) {
  152.  
  153.         //funckija koja dodaje predmet unutar uspjeha
  154.         //kandaidat ima 4 uspijeha (4 razreda), a svaki uspijeh ima niz predmeta u sebi
  155.         //ova funkcija ce zapravo dadavati predmete u razrede (uspjehe) kandidata
  156.         Predmet* pom = new Predmet[_brojPredmeta];
  157.         for (int i = 0; i < _brojPredmeta; i++) pom[i].Unos(_predmeti[i]._naziv, _predmeti[i]._ocjena, *_predmeti[i]._datumUnosa);
  158.         for (int i = 0; i < _brojPredmeta; i++) _predmeti[i].Dealociraj();
  159.         delete[] _predmeti;
  160.         _predmeti = nullptr;
  161.         _predmeti = new Predmet[_brojPredmeta + 1];
  162.         for (int i = 0; i < _brojPredmeta; i++) _predmeti[i].Unos(pom[i]._naziv, pom[i]._ocjena, *pom[i]._datumUnosa);
  163.         for (int i = 0; i < _brojPredmeta; i++) pom[i].Dealociraj();
  164.         delete[] pom;
  165.         pom = nullptr;
  166.         _predmeti[_brojPredmeta].Unos(predmet._naziv, predmet._ocjena, *predmet._datumUnosa);
  167.         _brojPredmeta++;
  168.     }
  169.  
  170. };
  171.  
  172. struct Kandidat {
  173.     eNacinStudiranja _nacinStudiranja;
  174.     char * _imePrezime;
  175.     shared_ptr<Uspjeh> _uspjeh[4];
  176.  
  177.     void Unos(eNacinStudiranja nacinStudiranja, char * imePrezime) {
  178.         int vel = strlen(imePrezime) + 1;
  179.         _imePrezime = new char[vel];
  180.         strcpy_s(_imePrezime, vel, imePrezime);
  181.         _nacinStudiranja = nacinStudiranja;
  182.         for (int i = 0; i < 4; i++)
  183.             _uspjeh[i] = nullptr;
  184.     }
  185.    
  186.     void Dealociraj() {
  187.         delete[] _imePrezime; _imePrezime = nullptr;
  188.         for (int i = 0; i < 4; i++) if(_uspjeh[i]!=nullptr) _uspjeh[i]->Dealociraj();
  189.  
  190.     }
  191.    
  192.     void Ispis() {
  193.         cout << crt << _imePrezime << " " << _nacinStudiranja;
  194.         for (int i = 0; i < 4; i++) if(_uspjeh[i]!=nullptr) _uspjeh[i]->Ispis();
  195.     }
  196.  
  197.     bool DodajPredmet(eRazred razred, Predmet predmet) {
  198.  
  199.         //ako razred nije definisan enumeracijom
  200.         if (razred != PRVI && razred != DRUGI && razred != TRECI && razred != CETVRTI) {
  201.             cout << "Zao nam je, razred nije definisan enumeracijom" << crt;
  202.             return false;
  203.         }
  204.        
  205.         //prvjera da li je datum predmeta prije roka prijave
  206.         bool predaoNaVrijeme=true;
  207.         if (*predmet._datumUnosa->_godina < *rokZaPrijavu._godina) predaoNaVrijeme = true;
  208.         if (*predmet._datumUnosa->_godina > *rokZaPrijavu._godina) predaoNaVrijeme = false;
  209.         if (*predmet._datumUnosa->_godina == *rokZaPrijavu._godina) {
  210.             if (*predmet._datumUnosa->_mjesec < *rokZaPrijavu._mjesec) predaoNaVrijeme = true;
  211.             if (*predmet._datumUnosa->_mjesec > *rokZaPrijavu._mjesec) predaoNaVrijeme = false;
  212.             if (*predmet._datumUnosa->_mjesec == *rokZaPrijavu._mjesec) {
  213.                 if (*predmet._datumUnosa->_dan < *rokZaPrijavu._dan) predaoNaVrijeme = true;
  214.                 if (*predmet._datumUnosa->_dan > *rokZaPrijavu._dan) predaoNaVrijeme = false;
  215.                 if (*predmet._datumUnosa->_dan == *rokZaPrijavu._dan) {
  216.                     if (*predmet._datumUnosa->_sati < *rokZaPrijavu._sati) predaoNaVrijeme = true;
  217.                     if (*predmet._datumUnosa->_sati>* rokZaPrijavu._sati) predaoNaVrijeme = false;
  218.                     if (*predmet._datumUnosa->_sati == *rokZaPrijavu._sati) {
  219.                         if (*predmet._datumUnosa->_minuti < *rokZaPrijavu._minuti) predaoNaVrijeme = true;
  220.                         if (*predmet._datumUnosa->_minuti > *rokZaPrijavu._minuti) predaoNaVrijeme = false;
  221.                         if (*predmet._datumUnosa->_minuti == *rokZaPrijavu._minuti) predaoNaVrijeme = true;
  222.                     }
  223.                 }
  224.             }
  225.         }
  226.         if (!predaoNaVrijeme) { //ako nije predao na vrijeme
  227.             cout << "Zao nam je, rok za prijavu je istekao" << crt;
  228.             return false;
  229.         }
  230.  
  231.  
  232.         bool PronsaoIstiRazred=false; //trazimo da li vec postoji predmeta u razredu koji smo primili kao parametar, tj da li ima vec
  233. alociran uspijeh sa tim razredom
  234.         int index = 0; //ako pronadjemo uspijeh sa tim razredom, cuvamo njegov index
  235.         for (int i = 0; i < 4; i++) { //prolazimo kroz sva 4 uspijeha (koji su pokazivaci na uspijehe!)
  236.             if (_uspjeh[i] != nullptr && _uspjeh[i]->_razred == razred) { //ako pokazivac poakzuje na nesto, tj ima nesto
  237. alocirano na sebi ili ima predmeta u njemu, a pri tome je isti razred kao onaj sto je predan u parametrima
  238.                 PronsaoIstiRazred = true; //znaci pronasli smo isti razred
  239.                 index = i; //pamtimo index uspijeha koji sadrzi taj razred
  240.                 break; //i mozemo napustiti petlju
  241.             }
  242.         }
  243.         if (PronsaoIstiRazred) { //ako smo pronasli razred/uspijeh
  244.             for (int i = 0; i < _uspjeh[index]->_brojPredmeta; i++) {//proazimo kroz sve predmete tog uspijeha, ciji index sada znamo
  245.                 if (strcmp(predmet._naziv, _uspjeh[index]->_predmeti[i]._naziv) == 0) { //ako medju predmetima istog tog razreda nadjemo predmet koji trebamo dodati
  246.                     cout << "U " << razred << ". razredu je vec dodan predmet: " << predmet._naziv << crt; //pisemo poruku da to ne mozemo raditi
  247.                     return false;
  248.                 }
  249.             }
  250.         }
  251.  
  252.         if (PronsaoIstiRazred) { //ako funcija i dalje ide, znaci mozemo dodati novi predmet u razred, te ako vec imamo tak razred
  253.             _uspjeh[index]->DodajPredmet(predmet); //samo u njega dodamo predmet
  254.             return true; //vratimo true
  255.         }
  256.         else { //ako nismo pronasli razred, moramo ga prvo kreirati
  257.             for (int i = 0; i < 4; i++) { //prolazimo kroz sve pokazivace na uspijeh
  258.                 if (_uspjeh[i] == nullptr) { //i trazimo prvi prazan, slobodan, da nema nista alocrano na njemu, nullptr, kako god
  259.                     _uspjeh[i] = make_shared<Uspjeh>(); //alociramo Uspijeh na prazan pokazivac (make_shared<Uspjeh> jeo kao new uspijeh)
  260.                     _uspjeh[i]->Unos(razred); //unesemo, napravimo taj novi razred
  261.                     _uspjeh[i]->DodajPredmet(predmet); //i u njega smjestimo predmet koji smo trebali
  262.                     return true;
  263.                 }
  264.             }
  265.         }
  266.         return false;   //ovo return false je tu za svaki slucaj, ako nesto krene po zlu da vrati "nisam dodao predmet, nesto je poslo po zlu"
  267.     }
  268.  
  269. };
  270.  
  271. Kandidat* rekNajboljaOcjena(Kandidat* kandidati, int brojKandidata, char* imePredmeta, int setac, int najvecaOcjena, int indexKandidata) {
  272.  
  273.     //bazni slucaj:
  274.     if (setac == brojKandidata) { //setac je index koji "seta" kroz kandidate, te kada dodje do koliko kandaidata ima, prekida se funkcija
  275.         Kandidat* pokazivac = &kandidati[indexKandidata]; //pokazivac koji uzima adresu kandidata koji je na pozicij koju smo pronasli
  276.         cout << "Kandidat sa najvecom ocjenom (" << najvecaOcjena << ") iz predmeta " << imePredmeta << " je: " << pokazivac->_imePrezime << endl;
  277.         return pokazivac;
  278.     }
  279.  
  280.     for (int i = 0; i < 4; i++) { //svaki kandaitat ima 4 uspijeha, kandaidati[setac] ce biti redom kandidati[0], [1], setac se povecava rekurzijom
  281.         if (kandidati[setac]._uspjeh[i] != nullptr) { //ako nadjemo uspijeh koji ima nesto alocirano, tj koji pokazuje na nesto ili ima predmeta u sebi
  282.             for (int j = 0; j < kandidati[setac]._uspjeh[i]->_brojPredmeta; j++) { //pisemo petlju koja prolazi kroz sve predmete nadjenog uspijeha
  283.                 if (strcmp(imePredmeta, kandidati[setac]._uspjeh[i]->_predmeti[j]._naziv) == 0) { //ako nadjemo predmet koji je predan kao parametar
  284.                     if (kandidati[setac]._uspjeh[i]->_predmeti[j]._ocjena == najvecaOcjena) break; //ako mu je ocjena ista break, jer prva ostaje zapamcena
  285.                     if (kandidati[setac]._uspjeh[i]->_predmeti[j]._ocjena > najvecaOcjena) { // ako je ocjena veca od najvece ocjene
  286.                         najvecaOcjena = kandidati[setac]._uspjeh[i]->_predmeti[j]._ocjena; //najveca ocjena postaje ta ocjena
  287.                         indexKandidata = setac; //pamtimo index kandidata gdje smo nasli tu ocjenu (setac je index kandidata)
  288.                     }
  289.                 }
  290.             }
  291.         }
  292.     }
  293.     setac++; //povecamo setac za jedan, da predjemo na sljedeceg kandidata
  294.     rekNajboljaOcjena(kandidati, brojKandidata, imePredmeta, setac, najvecaOcjena, indexKandidata);//ponovo pozivamo funkciju sa novo-popunjenim parametrima
  295.  
  296. }
  297.  
  298.  
  299. int main() {
  300.  
  301.     DatumVrijeme datum19062017_1015, datum20062017_1115, datum30062017_1215, datum05072017_1231;
  302.     datum19062017_1015.Unos(19, 6, 2017, 10, 15);
  303.     datum20062017_1115.Unos(20, 6, 2017, 11, 15);
  304.     datum30062017_1215.Unos(30, 6, 2017, 12, 15);
  305.     datum05072017_1231.Unos(5, 7, 2017, 12, 31);
  306.  
  307.     cout << "Funkcija GetDatumKaoNizKaraktera: ";
  308.     cout << datum19062017_1015.GetDatumKaoNizKaraktera() << endl<<endl; //19.6.2017 10:15
  309.    
  310.     Predmet Matematika, Fizika, Hemija, Engleski;
  311.     Matematika.Unos("Matematika", 2, datum19062017_1015);
  312.     Fizika.Unos("Fizika", 5, datum20062017_1115);
  313.     Hemija.Unos("Hemija", 2, datum20062017_1115);
  314.     Engleski.Unos("Engleski", 5, datum05072017_1231);
  315.  
  316.     int brojKandidata = 2;
  317.  
  318.     Kandidat * prijave2017 = new Kandidat[brojKandidata];
  319.     prijave2017[0].Unos(DL, "Jasmin Azemovic");
  320.     prijave2017[1].Unos(REDOVAN, "Indira Hamulic");
  321.  
  322.     cout << endl << "Unos predmeta:" << endl;
  323.     if (prijave2017[0].DodajPredmet(DRUGI, Engleski)) cout << "Predmet uspjesno dodan!" << crt; //ne
  324.     if (prijave2017[0].DodajPredmet(DRUGI, Matematika)) cout << "Predmet uspjesno dodan!" << crt;
  325.     if (prijave2017[0].DodajPredmet(PRVI, Fizika)) cout << "Predmet uspjesno dodan!" << crt;
  326.     if (prijave2017[0].DodajPredmet(PRVI, Hemija)) cout << "Predmet uspjesno dodan!" << crt;
  327.    
  328.     Matematika._ocjena = 5;
  329.     Hemija._ocjena = 3;
  330.  
  331.     if (prijave2017[1].DodajPredmet(PRVI, Matematika)) cout << "Predmet uspjesno dodan!" << crt;
  332.     if (prijave2017[1].DodajPredmet(PRVI, Matematika)) cout << "Predmet uspjesno dodan!" << crt; //ne
  333.     if (prijave2017[1].DodajPredmet(TRECI, Hemija)) cout << "Predmet uspjesno dodan!" << crt;
  334.     if (prijave2017[1].DodajPredmet(DRUGI, Engleski)) cout << "Predmet uspjesno dodan!" << crt; //ne
  335.     cout << "Kraj unosa predmeta" << endl;
  336.  
  337.     //lamda funkcija koja sa sobom enkapsulira (nosi sa sobom) orijave i broj kandidatat, nema parametre () te vraca pametni pokazivac na Uspijeh
  338.     auto najboljiUspjeh = [prijave2017, brojKandidata]()->shared_ptr<Uspjeh> {
  339.  
  340.         double najveciProsjek = 0; //cuvamo informaciju o najvecem prosjeku
  341.         int indexKandidata = 0; //cuvamo index kandidata koji ima taj prosjek
  342.         int indexUspijeha = 0; //cuvamo index uspijeha unutar kandidata
  343.         for (int i = 0; i < brojKandidata; i++) { //prolazimo kroz sve kandidate
  344.             for (int j = 0; j < 4; j++) { //svaki kandidat ima 4 uspijeha
  345.                 if (prijave2017[i]._uspjeh[j] != nullptr) { //ako uspijeh "pokazuje na nesto" odnosno nije nullptr
  346.                     double prosjek = 0; //inicijalizujemo prosjek
  347.                     //saberemo sve occjene u nizu _predmeti, koji se nalazi u uspijehu koji smo nasli
  348.                     for (int k = 0; k < prijave2017[i]._uspjeh[j]->_brojPredmeta; k++) prosjek += prijave2017[i]._uspjeh[j]->_predmeti[k]._ocjena;
  349.                     prosjek = double(prosjek) / prijave2017[i]._uspjeh[j]->_brojPredmeta; //prosjek je suma ocjena kroz broj predmeta
  350.                     if (prosjek == najveciProsjek) break; //ako neko prije vec ima isti prosjek, break, jer prvi prosjek treba da ostane sacuvan
  351.                     if (prosjek > najveciProsjek) { //ako je novi prosjek veci od najveceg prosjeka
  352.                         najveciProsjek = prosjek; //najveci prosjek postaje taj novi prosjek
  353.                         indexKandidata = i; //sacuvamo index od kandidata gdje smo nasli novi najveci prosjek (i)
  354.                         indexUspijeha = j; // te sacuvamo index uspijeha u kandidatu pod indexom i (j)
  355.                     }
  356.                 }
  357.             }
  358.         }
  359.         if (najveciProsjek == 0) return nullptr; //ako nisamo nista nasli, prosjek ce ostati na nuli, te onda vracamo nullptr
  360.         //pametni pokazivac koji pokazuje na uspijeh koji se nalazi na nadjenoj poziciji unutar kanditata koji se nalazi na nadjenoj poziciji
  361.         shared_ptr<Uspjeh> pokazivac = prijave2017[indexKandidata]._uspjeh[indexUspijeha];
  362.         return pokazivac; //vracamo taj pokazivac
  363.     };
  364.  
  365.     cout <<endl<<endl<< "Najbolji uspijeh po razredu pronadnjen LAMBDA funkcijom: ";
  366.     shared_ptr<Uspjeh> najbolji = najboljiUspjeh();
  367.     najbolji->Ispis();
  368.  
  369.     cout << endl << "Rekurzivno pronadjen kandidat sa najboljom ocjenom iz proslijedjenog predmeta: " << endl;
  370.     rekNajboljaOcjena(prijave2017, brojKandidata, "Matematika", 0, 0, 0);
  371.  
  372.     cout << endl << "Ispis i dealokacija svih kandidata, uspijeha i predmeta:" << endl;
  373.     for (int i = 0; i < brojKandidata; i++){
  374.         prijave2017[i].Ispis();
  375.         prijave2017[i].Dealociraj();
  376.     }
  377.     delete[] prijave2017;
  378.     prijave2017 = nullptr;
  379.     cout << endl;
  380. return 0;
  381. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement