Advertisement
Guest User

Untitled

a guest
Jan 22nd, 2019
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.70 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4. #include <regex>
  5. #include <sstream>
  6. #include <thread>
  7. #include <chrono>
  8. #include <mutex>
  9.  
  10. using namespace std;
  11.  
  12. const char *crt = "\n-------------------------------------------\n";
  13. enum OznakaKrvneGrupe { O, A, B, AB };
  14. const char* OznakaKrvneGrupeString[] = { "O", "A", "B", "AB" };
  15.  
  16. class Datum {
  17.     int _dan, _mjesec, _godina;
  18. public:
  19.     Datum(int dan, int mjesec, int godina) :
  20.         _dan(dan), _mjesec(mjesec), _godina(godina) {}
  21.    
  22.     Datum(const Datum &d)
  23.     {
  24.         _dan = d._dan;
  25.         _mjesec = d._mjesec;
  26.         _godina = d._godina;
  27.     }
  28.  
  29.     Datum &operator =(const Datum &d)
  30.     {
  31.         if(this != &d)
  32.         {
  33.             _dan = d._dan;
  34.             _mjesec = d._mjesec;
  35.             _godina = d._godina;
  36.         }
  37.         return *this;
  38.     }
  39.  
  40.  
  41.     string ToString(string separator = ".") const
  42.     {
  43.         stringstream s;
  44.  
  45.         s << _dan << separator << _mjesec << separator << _godina;
  46.  
  47.         return s.str();
  48.     }
  49.  
  50.     string ToString(string separator)
  51.     {
  52.         stringstream s;
  53.  
  54.         s << _dan << separator << _mjesec << separator << _godina;
  55.  
  56.         return s.str();
  57.     }
  58. };
  59.  
  60. template <class T1, class T2, int max>
  61. class Kolekcija {
  62.     T1 _elementi1[max];
  63.     T2 _elementi2[max];
  64.     int _trenutnoElemenata;
  65.     int _keyElement; // kljucni element, a podrazumijevano T1 predstavlja kljucni element i tada je vrijednost 1, a u slucaju da je T2 onda ce vrijednost biti 2
  66. public:
  67.     Kolekcija(int keyElement = 1) {
  68.         _trenutnoElemenata = 0;
  69.         _keyElement = keyElement;
  70.     }
  71.     bool AddElement(T1 ele1, T2 ele2) {
  72.         if (_trenutnoElemenata == max)
  73.             return false;
  74.         _elementi1[_trenutnoElemenata] = ele1;
  75.         _elementi2[_trenutnoElemenata] = ele2;
  76.         _trenutnoElemenata++;
  77.         return true;
  78.     }
  79.  
  80.     void Sort(string s)
  81.     {
  82.         bool promjena = true;
  83.         while (promjena)
  84.         {
  85.             promjena = false;
  86.  
  87.             for (int i = 0; i < _trenutnoElemenata-1; i++)
  88.             {
  89.                 if (s == "ASC" && _keyElement == 1 && _elementi1[i] > _elementi1[i + 1])
  90.                 {
  91.                     swap<T1, T1>(_elementi1[i], _elementi1[i + 1]);
  92.                     swap<T2, T2>(_elementi2[i], _elementi2[i + 1]);
  93.                     promjena = true;
  94.                 }
  95.  
  96.                 else if (s == "DESC" && _keyElement == 1 && _elementi1[i] < _elementi1[i + 1])
  97.                 {
  98.                     swap<T1, T1>(_elementi1[i], _elementi1[i + 1]);
  99.                     swap<T2, T2>(_elementi2[i], _elementi2[i + 1]);
  100.                     promjena = true;
  101.                 }
  102.                 if (s == "ASC" && _keyElement == 2 && _elementi2[i] > _elementi2[i + 1])
  103.                 {
  104.                     swap<T1, T1>(_elementi1[i], _elementi1[i + 1]);
  105.                     swap<T2, T2>(_elementi2[i], _elementi2[i + 1]);
  106.                     promjena = true;
  107.                 }
  108.  
  109.                 else if (s == "DESC" && _keyElement == 2 && _elementi2[i] < _elementi2[i + 1])
  110.                 {
  111.                     swap<T1, T1>(_elementi1[i], _elementi1[i + 1]);
  112.                     swap<T2, T2>(_elementi2[i], _elementi2[i + 1]);
  113.                     promjena = true;
  114.                 }
  115.             }
  116.         }
  117.     }
  118.  
  119.     void SetElement2(int lokacija, T2 ele2) {
  120.         _elementi2[lokacija] = ele2;
  121.     }
  122.     void SetKeyElement(int keyElement) {
  123.         if (keyElement < 1 || keyElement>2)
  124.             throw exception("Nedozvoljena vrijednost!");
  125.         _keyElement = keyElement;
  126.     }
  127.     int GetTrenutno() const { return _trenutnoElemenata; }
  128.     int GetMax() const { return max; }
  129.  
  130.     T1 GetElement1(int lokacija) const {
  131.         if (lokacija < 0 || lokacija >= _trenutnoElemenata)
  132.             throw exception("Nepostojeca lokacija!");
  133.         return _elementi1[lokacija];
  134.     }
  135.     T2 GetElement2(int lokacija) const {
  136.         if (lokacija < 0 || lokacija >= _trenutnoElemenata)
  137.             throw exception("Nepostojeca lokacija!");
  138.         return _elementi2[lokacija];
  139.     }
  140.     friend ostream &operator<<(ostream &COUT, const Kolekcija &obj) {
  141.         for (size_t i = 0; i < obj.GetTrenutno(); i++)
  142.             COUT << obj.GetElement1(i) << " " << obj.GetElement2(i) << endl;
  143.         return COUT;
  144.     }
  145. };
  146.  
  147. class KrvnaGrupa {
  148.     /*postoje 4 krvne grupe koje su navedene u enumeracije OznakaKrvneGrupe, pri cemu svaka od navedenih moze imati pozitivan (+) i negativan (-) Rh faktor*/
  149.     OznakaKrvneGrupe _oznaka;//npr: AB
  150.     char _rhFaktor; // + ili -
  151.                     /*prethodno pomenuto je izuzetno bitno iz razloga sto postoje jasna pravila vezana za darivanje krvi tj. koji primalac moze primiti krv od kojeg donatora sto je prikazano u tabeli, a naredna dva vector-a su zaduzena da cuvaju informacije o tome, npr. za krvnu grupu A+ vector donatori ce cuvati vrijednosti: A+ i AB+ */
  152.     vector<KrvnaGrupa> _donatori; //krvne grupe kojima odredjena krvna grupa moze donirati krv.
  153.     vector<KrvnaGrupa> _primaoci; //krvne grupe od kojih odredjena krvna grupa moze primiti krv.
  154. public:
  155.     KrvnaGrupa(){}
  156.     KrvnaGrupa(OznakaKrvneGrupe oznaka, char rhFaktor) :
  157.         _oznaka(oznaka), _rhFaktor(rhFaktor) {}
  158.     KrvnaGrupa(const KrvnaGrupa&k): _oznaka(k._oznaka), _rhFaktor(k._rhFaktor)
  159.     {
  160.  
  161.     }
  162.     void SetDonatori(vector<KrvnaGrupa> donatori) {
  163.         _donatori = donatori;
  164.     }
  165.     void SetPrimaoci(vector<KrvnaGrupa> primaoci) {
  166.         _primaoci = primaoci;
  167.     }
  168.  
  169.     bool operator == (const KrvnaGrupa &k)
  170.     {
  171.         if (_oznaka == k._oznaka && _rhFaktor == k._rhFaktor)
  172.             return true;
  173.         return false;
  174.     }
  175.  
  176.     /*
  177.     Ispis podataka o krvnoj grupi treba biti u formatu:
  178.     -------------------------------------------
  179.     Krvna grupa -> 0+
  180.     -------------------------------------------
  181.     Donori  ->  0+, A+, B+, AB+
  182.     Primaoci -> 0+, 0-
  183.     -------------------------------------------
  184.     */
  185.  
  186.     string ToString() const
  187.     {
  188.         stringstream s;
  189.  
  190.         s << crt;
  191.         s << "Krvna Grupa ->" << _oznaka << _rhFaktor;
  192.         s << crt;
  193.         s << "Donori ->";
  194.         for (int i = 0; i < _donatori.size(); i++)
  195.         {
  196.             s << _donatori[i]._oznaka << _donatori[i]._rhFaktor << ", ";
  197.         }
  198.         s << endl;
  199.         s << "Primaoci ->";
  200.         for (int i = 0; i < _primaoci.size(); i++)
  201.         {
  202.             s << _primaoci[i]._oznaka << _primaoci[i]._rhFaktor << ", ";
  203.         }
  204.         s << crt;
  205.  
  206.         return s.str();
  207.     }
  208.  
  209. };
  210.  
  211. //Klasu proglasiti apstraktnom
  212. class Osoba {
  213. protected:
  214.     char* _imePrezime;
  215.     KrvnaGrupa _krvnaGrupa;
  216. public:
  217.     Osoba(const char* imePrezime, KrvnaGrupa krvnaGrupa) : _krvnaGrupa(krvnaGrupa) {
  218.         int size = strlen(imePrezime) + 1;
  219.         _imePrezime = new char[size];
  220.         strcpy_s(_imePrezime, size, imePrezime);
  221.     }
  222.  
  223.     Osoba(const Osoba &o):_krvnaGrupa(o._krvnaGrupa)
  224.     {
  225.         int size = strlen(o._imePrezime) + 1;
  226.         _imePrezime = new char[size];
  227.         strcpy_s(_imePrezime, size, o._imePrezime);
  228.     }
  229.  
  230.     virtual ~Osoba() {
  231.         delete[] _imePrezime;
  232.         _imePrezime = nullptr;
  233.     }
  234.  
  235.     KrvnaGrupa GetKrvnaGrupa() { return _krvnaGrupa; }
  236. };
  237.  
  238. bool ValidanFormat(string telefon)
  239. {
  240.     string pravilo = "(\\d{3})[/-](\\d{3})[-](\\d{3})";
  241.     regex obj(pravilo);
  242.  
  243.     if (regex_match(telefon, obj))
  244.         return true;
  245.     return false;
  246. }
  247.  
  248.  
  249. class Donator : public Osoba {
  250.     //u slucaju da broj telefona nije u validnom formatu potrebno ga je postaviti na podrazumijevanu vrijednost: 000-000-000
  251.     string _telefon; //regex: 000/000-000 ili 000-000-000
  252.     Datum _datumPosljednjegDoniranja;
  253.     bool _podsjetiMe;
  254.     bool _kontaktirajMe;
  255.  
  256. public:
  257.     Donator(const char* imePrezime, KrvnaGrupa krvnaGrupa, string telefon, Datum dpd, bool remind = true, bool contact = true)
  258.         : Osoba(imePrezime, krvnaGrupa), _datumPosljednjegDoniranja(dpd) {
  259.         if (ValidanFormat(telefon))
  260.             _telefon = telefon;
  261.         else
  262.             _telefon = "000-000-000";
  263.     }
  264.  
  265.     Datum GetDatumDOniranja() { return _datumPosljednjegDoniranja; }
  266.  
  267.     Datum setDatumDoniranja(Datum dat)
  268.     {
  269.         return _datumPosljednjegDoniranja = dat;
  270.     }
  271.  
  272.     bool GetKontakt() { return _kontaktirajMe; }
  273. };
  274.  
  275. class Zahtjev {
  276.     string _ustanova;
  277.     Datum _datumZahtjeva;
  278.     KrvnaGrupa _krvnaGrupa;
  279.     double _kolicina;
  280. public:
  281.     Zahtjev(string ustanova, Datum datum, KrvnaGrupa krvnaGrupa, double kolicina) :
  282.         _ustanova(ustanova), _datumZahtjeva(datum), _krvnaGrupa(krvnaGrupa), _kolicina(kolicina) { }
  283.  
  284.     friend ostream& operator<<(ostream& COUT, const Zahtjev& obj) {
  285.         COUT << "Ustanova: " << obj._ustanova << endl;
  286.         COUT << "Datum: " << obj._datumZahtjeva.ToString() << endl;
  287.         COUT << "Krvna grupa: " << obj._krvnaGrupa.ToString() << endl;
  288.         COUT << "Kolicina: " << obj._kolicina << endl;
  289.         return COUT;
  290.     }
  291.  
  292.     KrvnaGrupa GetKrvnaGrupa() { return _krvnaGrupa; }
  293.     double GetKolicina() { return _kolicina; }
  294. };
  295. mutex m;
  296.  
  297. class TransfuzijskiCentar {
  298.     //stanje zaliha za svaku pojedinu krvnu grupu
  299.     Kolekcija<KrvnaGrupa*, double, 8> _zalihe;
  300.     //evidentira svaku donaciju krvi
  301.     Kolekcija<Osoba *, double, 100> _donacije;
  302.     vector<Zahtjev> _zahtjevi;
  303.  
  304. public:
  305.  
  306.     /*
  307.     prilikom svake donacije je potrebno povecati zalihe za tu krvnu grupu
  308.     ukoliko krvna grupa vec postoji na zalihi onda se uvecava samo njena kolicina
  309.     takodjer, donatoru se postavlja nova vrijednost datuma posljednje donacije
  310.     */
  311.     //datum donacije, donator, kolicina
  312.     Kolekcija<KrvnaGrupa*, double, 8> GetZalihe() { return _zalihe; }
  313.     Kolekcija<Osoba *, double, 100> GetDonacije() { return _donacije; }
  314.     vector<Zahtjev> GetZahtjev() { return _zahtjevi; }
  315.  
  316.     void AddDonaciju(Datum d, Osoba *o, double kolicina)
  317.     {
  318.         bool postoji = false;
  319.         for (int i = 0; i < _zalihe.GetTrenutno(); i++)
  320.         {
  321.             if (*_zalihe.GetElement1(i) == o->GetKrvnaGrupa())
  322.             {
  323.                 _zalihe.SetElement2(i, _zalihe.GetElement2(i) + kolicina);
  324.                 postoji = true;
  325.             }
  326.  
  327.             for (int j = 0; j < _donacije.GetTrenutno(); j++)
  328.             {
  329.                 dynamic_cast<Donator*>(_donacije.GetElement1(j))->setDatumDoniranja(d);
  330.             }
  331.  
  332.             if (!postoji)
  333.                 _zalihe.AddElement(new KrvnaGrupa(*_zalihe.GetElement1(i)), kolicina);
  334.         }
  335.  
  336.  
  337.         Donator *donator = dynamic_cast<Donator*>(o);
  338.         _donacije.AddElement(new Donator(*donator), kolicina);
  339.     }
  340.  
  341.  
  342.     /*ukoliko transfuzijski centar posjeduje zahtijevane kolicine na stanju, odmah ce ih ustupiti prema zahtjevu,
  343.     a u slucaju da ne posjeduje onda ce (koristeci multithreading) kontaktirati (poslati SMS poruku sa odgovarajucim sadrzajem)
  344.     sve donore koji zadovoljavaju sljedece uslove:
  345.     - mogu donirati krv zahtijevanoj krvnoj grupi
  346.     - oznacili su da zele biti kontaktirani
  347.     - nisu davali krv u posljednja 3 mjeseca
  348.     */
  349.  
  350.     void DodajZahtjev(Zahtjev z)
  351.     {
  352.  
  353.         bool posjeduje = false;
  354.         for (int i = 0; i < _zahtjevi.size(); i++)
  355.         {
  356.             if (_zahtjevi[i].GetKolicina() >= z.GetKolicina())
  357.             {
  358.                 _zahtjevi.push_back(z);
  359.                 posjeduje = true;
  360.             }
  361.         }
  362.  
  363.         if (!posjeduje)
  364.         {
  365.             thread t([this, &z]() {
  366.                 m.lock();
  367.                 for (int i = 0; i < this->GetDonacije().GetTrenutno(); i++)
  368.                 {
  369.                     Donator *d = dynamic_cast<Donator*>(this->GetDonacije().GetElement1(i));
  370.  
  371.                     for (int j = 0; j < this->GetZalihe().GetTrenutno(); j++)
  372.                     {
  373.                         if (d->GetKrvnaGrupa() == *this->GetZalihe().GetElement1(j) && d->GetKontakt() == true)
  374.                         {
  375.                             cout << "Javite se u obliznji Transfuzijski centar!";
  376.                         }
  377.                     }
  378.                 }
  379.  
  380.  
  381.                 m.unlock();
  382.  
  383.             });
  384.             t.join();
  385.         }
  386.  
  387.  
  388.     }
  389.  
  390. };
  391.  
  392. void main() {
  393.  
  394.     /**************************************************************************
  395.     1. SVE KLASE TREBAJU POSJEDOVATI ADEKVATAN DESTRUKTOR
  396.     2. NAMJERNO IZOSTAVLJANJE KOMPLETNIH I/ILI POJEDINIH DIJELOVA DESTRUKTORA KOJI UZROKUJU RUNTIME ERROR CE BITI OZNACENO KAO "RE"
  397.     3. SPASAVAJTE PROJEKAT KAKO BI SE SPRIJECILO GUBLJENJE URADJENOG ZADATKA
  398.     4. PROGRAMSKI CODE SE TAKODJER NALAZI U FAJLU code.TXT
  399.     5. NAZIVI FUNKCIJA MORAJU BITI IDENTIÈNI ONIMA KOJI SU KORIŠTENI U TESTNOM CODE-U.OSTALE, POMOÆNE FUNKCIJE MOŽETE IMENOVATI PO ŽELJI. TAKOÐER, MOŽETE DODAVATI KOLIKO ŽELITE TESTNIH PODATAKA
  400.     ****************************************************************************/
  401.     Datum dat_12_01_2018(12, 1, 2018), dat_01_02_2018(1, 2, 2018);
  402.     cout << dat_01_02_2018.ToString() << endl; //podrazumijevani separator je tacka ".", pa ispisuje 1.2.2018
  403.     cout << dat_12_01_2018.ToString("/") << endl; //separator je proslijedjen, pa ispisuje 12/1/2018
  404.  
  405.     Kolekcija<int, int, 10> kolekcija1;
  406.     for (size_t i = 0; i < kolekcija1.GetMax(); i++)
  407.         if (!kolekcija1.AddElement(i, 170000 + i))
  408.             cout << "Elementi " << i << " i " << 170000 + i << " nisu dodati u kolekciju" << endl;
  409.  
  410.     cout << kolekcija1.GetElement1(0) << " " << kolekcija1.GetElement2(0) << endl;
  411.  
  412.     kolekcija1.Sort("ASC"); //kljucne rijeci za sortiranje su ASC i DESC, a sortiranje se vrsi prema kljucnom elementu
  413.     cout << kolekcija1 << endl << endl << endl;
  414.     kolekcija1.Sort("DESC");
  415.     cout << kolekcija1 << endl;
  416.  
  417.     kolekcija1.SetKeyElement(2);//postavlja kljucni element na T2
  418.  
  419.     kolekcija1.Sort("DESC"); //sada se sortiranje vrsi po elementu T2
  420.     cout << kolekcija1 << endl;
  421.  
  422.     KrvnaGrupa
  423.         O_poz(O, '+'), O_neg(O, '-'),
  424.         A_poz(A, '+'), A_neg(A, '-'),
  425.         B_poz(B, '+'), B_neg(B, '-'),
  426.         AB_poz(AB, '+'), AB_neg(AB, '-');
  427.  
  428.     vector<KrvnaGrupa> donori_O_poz{ O_poz, A_poz, B_poz, AB_poz };
  429.     O_poz.SetDonatori(donori_O_poz);
  430.     //ili krace napisano
  431.     O_poz.SetPrimaoci(vector<KrvnaGrupa>{O_poz, O_neg});
  432.     A_poz.SetDonatori(vector<KrvnaGrupa>{A_poz, AB_poz});
  433.     A_poz.SetPrimaoci(vector<KrvnaGrupa>{O_poz, A_poz, O_neg, A_neg});
  434.  
  435.     B_poz.SetDonatori(vector<KrvnaGrupa>{B_poz, AB_poz});
  436.     B_poz.SetPrimaoci(vector<KrvnaGrupa>{O_poz, B_poz, O_neg, B_neg});
  437.     /*
  438.     Ispis podataka o krvnoj grupi treba biti u formatu:
  439.     -------------------------------------------
  440.     Krvna grupa -> 0+
  441.     -------------------------------------------
  442.     Donori  ->  0+, A+, B+, AB+
  443.     Primaoci -> 0+, 0-
  444.     -------------------------------------------
  445.     */
  446.     cout << O_poz.ToString() << endl;
  447.  
  448.     Osoba * jasmin = new Donator("Jasmin Azemovic", B_poz, "061-111-222", Datum(12, 2, 2017), true, true);
  449.     Osoba * adel = new Donator("Adel Handzic", A_neg, "061-222-333", Datum(9, 1, 2017), true, true);
  450.     Osoba * goran = new Donator("Goran Skondric", B_neg, "061-333-444", Datum(9, 3, 2017), true, true);
  451.  
  452.  
  453.     TransfuzijskiCentar tcMostar;
  454.     /*
  455.     prilikom svake donacije je potrebno povecati zalihe za tu krvnu grupu
  456.     ukoliko krvna grupa vec postoji na zalihi onda se uvecava samo njena kolicina
  457.     takodjer, donatoru se postavlja nova vrijednost datuma posljednje donacije
  458.     */
  459.     //datum donacije, donator, kolicina
  460.     tcMostar.AddDonaciju(Datum(20, 5, 2017), jasmin, 2.5);
  461.     tcMostar.AddDonaciju(Datum(20, 5, 2017), adel, 3);
  462.     tcMostar.AddDonaciju(Datum(6, 5, 2017), goran, 1.2);
  463.  
  464.  
  465.     tcMostar.AddDonaciju(Datum(10, 9, 2017), jasmin, 2);
  466.     tcMostar.AddDonaciju(Datum(18, 10, 2017), adel, 1.8);
  467.     tcMostar.AddDonaciju(Datum(15, 9, 2017), goran, 3.8);
  468.  
  469.     Zahtjev zahtjev_0_poz("Tranfuziologija KCUS", Datum(18, 2, 2018), O_poz, 15),
  470.         zahtjev_0_neg("Tranfuziologija Bakir Nakas", Datum(20, 2, 2018), O_neg, 8);
  471.  
  472.     /*ukoliko transfuzijski centar posjeduje zahtijevane kolicine na stanju, odmah ce ih ustupiti prema zahtjevu,
  473.     a u slucaju da ne posjeduje onda ce (koristeci multithreading) kontaktirati (poslati SMS poruku sa odgovarajucim sadrzajem)
  474.     sve donore koji zadovoljavaju sljedece uslove:
  475.     - mogu donirati krv zahtijevanoj krvnoj grupi
  476.     - oznacili su da zele biti kontaktirani
  477.     - nisu davali krv u posljednja 3 mjeseca
  478.     */
  479.     tcMostar.DodajZahtjev(zahtjev_0_poz);
  480.     tcMostar.DodajZahtjev(zahtjev_0_neg);
  481.  
  482.     ////printa zahvalnice (zahvaljujemo se ime i prezime donatoru na ukupno doniranih X doza krvi) za TOP 2 donatora krvi
  483.     //tcMostar.GetZahvalniceZahvalnice(2);
  484.  
  485.     //delete adel;
  486.     //delete jasmin;
  487.     //delete goran;
  488. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement