izrađeni tutorijali i zadace (2011-2012)-tehnike programiranja

199
Izrađeni tutorijali(2011/2012), neki zadaci sa parcijalnih ispita, zadace(2011/2012) iz predmeta TEHNIKE PROGRAMIRANJA Zadaci su rađeni tokom cijelog semestra dok je trajao kurs, tako da izrada nekih zadataka s prvih tutorijala bi možda mogla biti i jednostavnije izvedena, ali možda je način razmišljanja s raspoloživim znanjem do tog tutorijala pogodniji. Greške su moguće i zadaci sa zadaća ne prolaze 100% svaki autotest, ali su bili dovoljno dobri za 80% bodova. Izrada zadataka: Tajma Kovačević Eman Jašarević

Upload: nedim-avicena-alic

Post on 26-Jul-2015

1.092 views

Category:

Documents


24 download

TRANSCRIPT

Page 1: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

Izrađeni tutorijali(2011/2012), neki zadaci sa parcijalnih ispita, zadace(2011/2012) iz predmeta TEHNIKE PROGRAMIRANJA Zadaci su rađeni tokom cijelog semestra dok je trajao kurs, tako da izrada nekih zadataka s prvih tutorijala bi možda mogla biti i jednostavnije izvedena, ali možda je način razmišljanja s raspoloživim znanjem do tog tutorijala pogodniji. Greške su moguće i zadaci sa zadaća ne prolaze 100% svaki autotest, ali su bili dovoljno dobri za 80% bodova.

Izrada zadataka: Tajma Kovačević Eman Jašarević

Page 2: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

Zadaci za Tutorial 1. 1. Napišite program koji će na ekranu ispisati vaše lične podatke u sljedećem obliku: Vaše ime i prezime ------------------ ime podvući crticama ostaviti jedan prazan red Datum rođenja Smjer studija Grad Program napišite u C++ stilu, koristeći biblioteku “iostream” i objekat izlaznog toka “cout”. 2. Napišite program koji izračunava koliko je keramičkih pločica potrebno za popločavanje bazena čije se dimenzije u metrima unose sa tastature. Dimenzije pločica u centimetrima se također unose sa tastature. Program nakon pokretanja treba da na ekranu proizvede dijalog poput sljedećeg (naravno, brojevi koje korisnik zadaje odabrani su proizvoljno): Unesi dimenzije bazena (axbxc) u metrima: 5 15 3 Unesi dimenzije pločice (axb) u centimetrima: 10 10 Za popločavanje bazena dimenzija 5x15x3 m sa pločicama dimenzija 10x10 cm potrebno je 19500 pločica. Prećutno pretpostavite da su dimenzije zadane tako da je popločavanje uvijek izvodivo sa cijelim brojem pločica. Za unos podataka i ispis rezultata koristite objekte “cin” i “ cout” iz biblioteke “iostream”. 3. Napišite program koji traži da se sa tastature unesu tri realna broja a, b i c, i koji ispisuje da li ta tri broja mogu biti stranice nekog trougla. Podsjetimo se da za stranice trougla mora vrijediti uvjet da su sve pozitivne i da je zbir dužina ma koje dvije stranice veći od dužine treće stranice. Ukoliko uneseni brojevi mogu predstavljati dužine stranica trougla, treba izračunati njegov najveći ugao i ispisati njegovu vrijednost u stepenima, minutama i sekundama. Za računanje ugla koristite kosinusnu teoremu prema kojoj je c2 = a2 + b2 – 2 a b cos γ (i analogno tome za preostale kombinacije stranica i uglova). Računajte da 1 radijan ima 180/π stepeni, dok vrijednost π možete računati po formuli π = 4 ⋅ arctg 1. Ukoliko uneseni brojevi ne mogu predstavljati dužine stranica trougla, treba ispisati odgovarajući komentar. Dijalozi koje formira program trebaju izgledati poput sljedećih: Unesite tri broja: 6 4 3 Najveći ugao trougla sa duzinama stranicama 5, 10 i 7 ima 117 stepeni, 16 minuta i 46 sekundi. Unesite tri broja: 5 15 7 Ne postoji trougao cije su duzine stranica 5, 15 i 7 Za unos podataka i ispis rezultata koristite objekte “cin” i “ cout” iz biblioteke “iostream”, a za odgovarajuća računanja funkcije iz biblioteke “cmath”. 4. Napišite program koji traži da se sa tastature unese prirodan broj n. U slučaju da korisnik unese nešto što nije prirodan broj (što uključuje i situaciju kada uneseni podatak uopće nije broj), treba ispisati poruku upozorenja, i ponoviti unos. Ukoliko je unos ispravan, program treba da izračuna i ispiše sumu svih djelilaca broja n. Na primjer, za n = 12 treba ispisati vrijednost 28, jer su djelioci broja 12 brojevi 1, 2, 3, 4, 6 i 12, a 1 + 2 + 3 + 4 + 6 + 12 = 28. Nakon toga, program treba da traži unos novog broja i da ponavlja postupak sve dok se kao broj ne unese nula.

Izrada tutorijala 1.

T1-1

#include <iostream> using namespace std; int main() {

Page 3: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

cout<<"Tajma Kovacevic"<<endl<<"-----------------------"<<endl<<"20.6.1992.god."<<endl<<"Elektroenergetika"<<endl<<"Mostar <3 <3 <3"<<endl; return 0; } T1-2 #include <iostream> using namespace std; int main() { cout<<"Unesite dimenzije bazena (a*b*c) u metrima->"<<endl; int a,b,c; cin>>a>>b>>c; while (!cin) { cout<<"Niste unijeli ispravno brojeve"<<endl; cin.clear(); cin.ignore(10000,'\n'); cin>>a>>b>>c; } //if((cin.peek()!=' ')||(cin.peek()!='\n'))cout<<"Niste unijeli cijele brojeve!"<<endl; /*Ukoliko vam kompajler ne prepoznaje realne brojeve kao gresku, tj realni brojevi ne izazivaju neispravno stanje objekta cout onda samo dodate ovaj prvi dio naredbe if...*/ cout<<"Unesite dimenzije plocica(d*e) u centimetrima->"<<endl; int d,e; cin>>d>>e; while (!cin) { cout<<"Niste unijeli ispravno brojeve"<<endl; cin.clear(); cin.ignore(10000,'\n'); cin>>d>>e; } cout<<"Za poplocavanje bazena dimenzija("<<a<<"*"<<b<<"*"<<c<<")potrebno je "<<(((a*100)*(b*100))+(2*(a*100)*(c*100))+(2*(b*100)*(c*100)))/(d*e)<<" plocica."; return 0; } T1-3 #include <iostream> #include <cmath> using namespace std; int main() {

Page 4: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

cout<<"Unesite tri broja:"; double a,b,c; cin>>a>>b>>c; //kontrola toka programa while (!cin) { cout<<"Niste unijeli ispravno stranice!"<<endl<<"Unesite ponovo->"<<endl; cin.clear(); cin.ignore(10000,'\n'); cin>>a>>b>>c; } while ((a<0)||(b<0)||(c<0)) { cout<<"Niste unijeli ispravno stranice!"<<endl<<"Unesite ponovo->"<<endl; cin.clear(); cin.ignore(100,'\n'); cin>>a>>b>>c; } //uvjet za trougao if (((a+b)>c)&&((b+c)>a)&&((a+c)>b)) { cout<<"Postoji trougao"<<endl; double alfa,beta,gama; alfa=acos((c*c+b*b-a*a)/(2*a*b)); beta=acos((a*a+c*c-b*b)/(2*a*c)); gama=acos((a*a+b*b-c*c)/(2*a*b)); double max=0; if (alfa>max)max=alfa; if (beta>max)max=beta; if (gama>max)max=gama; double ugao; ugao=max*(180/(4*atan(1))); /*Postoji varijanta da se najveci ugao izracuna nad najvecom stranicom, ali onda se moraju uzimati i dodatni uvjeti kad su sva tri ugla jednaka.Pa je pogodnije "PRONACI" najveci*/ double minute,sekunde,stepeni; int m,sec;//cuvaju minute i sekunde sa zarezom stepeni=int(ugao);

Page 5: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

m=(ugao- int(ugao))*60; sec=(m-int(m))*60; minute=int(m); sekunde=int(sec); cout<<"stepeni"<<stepeni<<endl; cout<<"minute"<<minute<<endl; cout<<"sekunde"<<sekunde<<endl; cout<<"Najveci trougao zadanog trougla iznosi:"<<stepeni<<"stepeni, "<<minute<<"minuta i "<<sekunde<<"sekundi."<<endl; } else { cout<<"Ne postoji trougao cije su stranice"<<a<<","<<b<<","<<c<<"!"<<endl; } return 0; } T1-4 #include <iostream> using namespace std; int main() { int n; do { cout<<endl<<"Unesite prirodan broj n->"; cin>>n; if (((cin.peek())!=' ')&&((cin.peek())!='\n'))cout<<"Niste unijeli prirodan broj!"<<endl; cin.ignore(10000,'\n'); while ((!cin)||(n<0)) { cout<<endl<<"Ponovo unesite vas broj->"; cin.clear(); cin.ignore(10000,'\n'); cin>>n; cin.ignore(100,'\n');

Page 6: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

} int suma(0); for (int i=1;i<=n;i++) { if (n%i==0)suma+=i; } cout<<endl<<"Suma djelilaca unesenog broja je->"<<suma; } while (n!=0); return 0; }

Page 7: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

Zadaci za Tutorial 2. 1. Napišite program koji će prvo tražiti od korisnika da unese dva prirodna broja “a” i “ b”, a koji zatim ispisuje tablicu kvadrata i kubova svih prirodnih brojeva “N” u opsegu od “a” do “b” uključivo. Tablica bi trebala da izgleda poput tablice na sljedećoj slici, koja prikazuje izgled tablice za vrijednosti 8 i 11 respektivno za “a” i “ b”: +-----+-------+---------+ | N | N^2 | N^3 | +-----+-------+---------+ | 8 | 64 | 512 | | 9 | 81 | 729 | | 10 | 100 | 1000 | | 11 | 121 | 1331 | +-----+-------+---------+

Za formatiranje ispisa koristite manipulator “setw ”. Radi ispravnog formatiranja tablice, pretpostavite da “a” i “ b” neće biti veći od 100. 2. U teoriji električnih kola uvodi se pojam impedanse, koja je kompleksan broj Z definiran kao Z = R+Xi, gdje je R tzv. aktivni otpor, a X tzv. reaktivni otpor (ili reaktansa), koji može biti i negativan. Ukoliko imamo paralelni spoj n elemenata čije su impedanse Z1, Z2, ... Zn, ukupna impedansa paralelne veze Z računa se kao Z = 1 / (1 / Z1 + 1 / Z2 + ... + 1 / Zn). Drugim riječima, situacija je slična paralelnom spajanju otpornika, osim što se ovdje radi sa kompleksnim impedansama. Napišite program u kojem se od korisnika traži da unese broj elemenata n a zatim n parova vrijednosti Rk i Xk za sve k od 1 do n (koje predstavljaju aktivne i reaktivne otpornosti svakog od n elemenata), i koji nakon toga računa i ispisuje aktivni i reaktivni otpor paralelne veze svih n elemenata. Dijalog između programa i korisnika treba da izgleda poput sljedećeg: Unesi broj elemenata: 3 R1 = 3.5 X1 = 2.8 R2 = 10 X2 = -1.54 R3 = 12.37 X3 = 0.24 Paralelna veza ovih elemenata ima R = 2.51479 i X = 0.897637.

Za realizaciju programa koristite kompleksni tip podataka. Nemojte koristiti niti nizove niti vektore, nego sumu 1 / Z1 + 1 / Z2 + ... + 1 / Zn računajte “u hodu”, uporedo sa unosom podataka. 3. Prepravite prethodni program tako što će se sve impedanse Zk umjesto preko aktivnog otpora Rk

i reaktivnog otpora Xk zadavati preko tzv. prividnog otpora Zk i faznog pomaka ϕk, pri čemu vrijedi Zk = Zk eiϕk. Program na kraju treba prikazati prividni otpor i fazni pomak za čitavu paralelnu vezu. Fazni pomak treba zadavati ispisivati u stepenima. Uputa: trebaće vam funkcije “abs ”, “ arg ” i “ polar ”. Unesi broj elemenata: 2 Z1 = 10.5 fi1 = 30 Z2 = 2.8 fi2 = -47.6 Paralelna veza ovih elemenata ima Z = 2.57147 i fi = -33.7613.

2 4. Napišite funkciju koja kao parametar prima vektor realnih brojeva. Funkcija treba da ispita da li elementi vektora čine slijed koji se periodično ponavlja ili ne. Na primjer, za vektor čiji su elementi 5, 9, 7, 2, 5, 9, 7, 2, 5, 9, 7 uočavamo da njegovi elementi čine slijed koji se periodično ponavlja sa dužinom perioda 4. Ukoliko elementi vektora čine periodičan slijed, funkcija treba da vrati kao rezultat dužinu perioda, a u suprotnom, funkcija treba da vrati nulu kao rezultat. Napisanu funkciju demonstrirajte u glavnom programu u kojem ćete unositi elemente sa tastature u neki vektor sve dok se sa tastature ne unese nula, koja označava kraj unosa (tu nulu ne treba smjestiti u vektor). Nakon završetka unosa, program poziva napisanu funkciju sa ciljem da utvrdi da li se elementi periodično ponavljaju ili ne, nakon čega ispisuje odgovarajuči

Page 8: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

komentar na ekranu (informaciju o dužini perioda, ili da elementi ne čine periodičan slijed). Napomenimo da nije unaprijed poznato koliko će korisnik unijeti elemenata prije nego što unese nulu kao oznaku završetka unosa. Izrada tutorijala 2. T2-1

#include <iostream> #include<iomanip> using namespace std; int main() { int a,b; cout<<"Unesite dva prirodna broja->"<<endl; cin>>a>>b; if (((cin.peek())!=' ')&&((cin.peek())!='\n'))cout<<"Niste unijeli prirodan broj!"<<endl; cin.ignore(10000,'\n'); while ((!cin)||(a<0)||(b<0)) { cout<<endl<<"Ponovo unesite vase brojeve->"; cin.clear(); cin.ignore(10000,'\n'); cin>>a>>b; cin.ignore(100,'\n'); } cout<<"+---+-----+-------+"<<endl; cout<<"| N | N^2| N^3 |"<<endl; cout<<"+---+-----+-------+"<<endl; for (int i=a;i<=b;i++) { cout<<"|"<<setw(3)<<i<<"|"<<setw(5)<<i*i<<"|"<<setw(7)<<i*i*i<<"|"<<endl; } cout<<"+---+-----+-------+"<<endl; return 0; } T2-2 #include <iostream> #include<complex>

Page 9: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

using namespace std; int main() { cout<<"Unesite broj elementa za koje racunate impedansu->"<<endl; int n; cin>>n; if (((cin.peek())!=' ')&&((cin.peek())!='\n')) cout<<"Niste unijeli prirodan broj!"<<endl; cin.ignore(10000,'\n'); while ((!cin)||(n<0)) { cout<<endl<<"Ponovo unesite vase brojeve->"; cin.clear(); cin.ignore(10000,'\n'); cin>>n; cin.ignore(100,'\n'); } complex<double>suma(0,0); for(int i=1;i<=n;i++) { double r,x; cout<<"R"<<i<<"="; cin>>r; cout<<"X"<<i<<"="; cin>>x; suma+=complex<double>(1,0)/complex<double>(r,x); } cout<<"suma"<<suma<<endl; complex<double>impedansa; impedansa=complex<double>(1,0)/suma; cout<<"Impedansa ove paralelne veze je R="<<real(impedansa)<<endl<<"i X="<<imag(impedansa)<<endl; ; return 0;

Page 10: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

T2-3 #include <iostream> #include<complex> using namespace std; int main() { cout<<"Unesite broj elementa za koje racunate impedansu->"<<endl; int n; cin>>n; if (((cin.peek())!=' ')&&((cin.peek())!='\n')) cout<<"Niste unijeli prirodan broj!"<<endl; cin.ignore(10000,'\n'); while ((!cin)||(n<0)) { cout<<endl<<"Ponovo unesite vase brojeve->"; cin.clear(); cin.ignore(10000,'\n'); cin>>n; cin.ignore(100,'\n'); } complex<double>suma(0,0); for (int i=1;i<=n;i++) { double z,fi; cout<<"Z"<<i<<"="; cin>>z; cout<<"fi"<<i<<"="; cin>>fi; complex<double>k; k=polar(z,fi); suma+=complex<double>(1,0)/k; cout<<k<<endl; } //cout<<"suma"<<suma<<endl;

Page 11: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

complex<double>impedansa; impedansa=complex<double>(1,0)/suma; cout<<"Impedansa ove paralelne veze je Z="<<abs(impedansa)<<" i fi="<<arg(impedansa)<<endl; ; return 0; } T2-4 #include <iostream> #include <vector> using namespace std; int fja (vector<int> a, int x){ bool ponavlja(true); int c; for(int i=0;i<a.size();i++){ for(int j=i;j<a.size();j+=x){ if(a[j]!=a[i]) { ponavlja=false; } } if(ponavlja==false) { break; } } if(ponavlja==true) { c=x;} else { c=0; } return c; } int main() { vector <int> brojevi; vector <int> brojac; int n; do { cout << "Unesi broj: " << endl; cin>>n; if(n!=0) brojevi.push_back(n); } while(n!=0); for(int i=1;i<brojevi.size();i++){ if(brojevi[i]==brojevi[0]) { brojac.push_back(i); } } int e(0),d(0); while(e<brojac.size()) { int b=brojac[e];

Page 12: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

d=fja(brojevi,b); if(d!=0) { break; } else { e++;} } cout<<"Period je: "<<d<<endl; return 0; }

Zadaci za Tutorial 3. 1. Napišite program koji traži da se prvo unese prirodan broj “n”, a nakon toga elementi vektora “a” koji ima “n” cjelobrojnih elemenata, za koje ćemo prećutno pretpostaviti da su svi prirodni brojevi, tj. veći od nule (ovu pretpostavku ne treba provjeravati u programu). Zatim, program treba da kreira dva nova vektora “b” i “ c”, i da u vektor “b” prepiše sve proste brojeve iz vektora “a” (tj. one djeljive samo sa 1 i sa samim sobom), a u vektor “c” sve složene brojeve iz vektora “a” (tj. one koje imaju više od dva djelioca). Konačno, program treba da u jednom redu ispiše elemente vektora “b”, a u drugom redu elemente vektora “c”. Brojevi trebaju biti međusobno razdvojeni zarezom, pri čemu iza posljednjeg broja u svakom redu ne treba da bude zarez. Na primjer, ukoliko se u vektor “a” unese slijed brojeva 3, 4, 2, 5, 9, 4, 10, 1, 15, 13, 8 i 2, ispis na ekranu treba da bude 3,2,5,7,13,2 4,9,4,10,15 s obzirom da se broj 1 ne smatra ni prostim ni složenim. Posebno testirajte slučajeve kada su svi uneseni brojevi parni ili kada su svi uneseni brojevi neparni. 2. Prepravite prethodni tako da umjesto tipa “vector ” koristi tip “deque ” (tj. da koristi dek umjesto vektora), i uvjerite se da sve i dalje radi isto. Zatim, zamijenite poziv funkcije “push back ” sa pozivom funkcije “push front ” i uporedite razliku. 3. Napravite funkciju “TablicaMnozenja ” koja prima dva cjelobrojna parametra “m” i “ n” koja kreira matricu formata m × n organiziranu kao vektor vektôrā sa cjelobrojnim elementima, popunjava je “tablicom množenja” pri čemu množenici u redovima tablice idu od 1 do m a množitelji u kolonama tablice od 1 do n, i na kraju, vraća tako kreiranu matricu kao rezultat. Na primjer, za m = 3 i n = 5 kreirana matrica treba da ima elemente kako je prikazano ispod: 1 2 3 4 5 2 4 6 8 10 3 6 9 12 15 Napisanu funkciju demonstrirajte u testnom programu u kojem se sa tastature unose brojevi m i n, zatim kreira matrica formata m × n koja predstavlja tablicu množenja kako je opisano gore, i na kraju ispisuje kreiranu matricu uredno poravnatu na način sličan kako je prikazano gore. Za ispis svakog elementa matrice zauzmite po 5 mjesta (pomoću manipulatora “setw ”). 4. Napišite funkciju “PascalovTrougao ” (ili “ PascalovTrokut ”) koja ima jedan cjelobrojni parametar “n”. Ova funkcija treba kreirati strukturu “grbave matrice” sa “n” redova u kojoj prvi red ima jedan element, drugi red dva elementa, treći red tri elementa, itd. koju nakon kreiranja treba popuniti elementima Pascalovog trougla (trokuta) sa “n” redova. Funkcija treba da kao rezultat vrati upravo tako kreiranu “grbavu matricu”. Funkciju testirajte u programu koji za unesenu vrijednost “n” sa tastature ispisuje Pascalov trougao (trokut) sa “n” redova. Na primjer, za unesenu vrijednost 7 ispis na ekranu treba izgledati poput sljedećeg: 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 1 6 15 20 15 6 1 Pri tome, elemente Pascalovog trougla nije dozvoljeno računati preko binomnih koeficijenata,

Page 13: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

već treba koristiti činjenicu da je svaki element Pascalovog trougla jednak zbiru elemenata koji se nalaze tačno iznad njega, i njegovog susjeda sa lijeve strane. 2 5. Napišite funkciju sa dva parametra, od kojih je prvi tipa “string ”, a drugi cjelobrojnog tipa. Prvi parametar predstavlja neku rečenicu, a drugi parametar redni broj riječi unutar te rečenice. Funkcija treba da izdvoji tu riječ iz rečenice, i da vrati kao rezultat tako izdvojenu riječ. Na primjer, ukoliko je kao prvi parametar zadan tekst “ Na vrh brda vrba mrda” a kao drugi parametar broj 4, funkcija treba kao rezultat da vrati string “vrba”. Ovdje pod pojmom riječ podrazumijevamo bilo koji slijed uzastopnih znakova koji nisu razmaci, a ispred kojeg se eventualno nalazi razmak (ili ništa), i iza kojeg eventualno slijedi razmak (ili ništa). Tako se, na primjer, u tekstu “Kiša pada.Trava raste” slijed znakova “pada.Trava” tretira kao jedna riječ (druga po redu), jer iza tačke nema razmaka (ovakav tretman vrijedi i u tekst procesorima poput Microsoft Word-a). Obratite pažnju da riječi mogu biti razdvojene sa više uzastopnih razmaka, kao i da na početku i kraju teksta može, ali i ne mora biti razmaka. Ukoliko je drugi parametar manji od 1 ili veći od broja riječi u rečenici, funkcija treba baciti izuzetak. Napisanu funkciju demonstrirajte u testnom programu u kojem se za rečenicu unesenu sa tastature i prirodan broj n ispisuje n-ta riječ te rečenice (pozivom napisane funkcije). U testnom programu obavezno predvidite hvatanje izuzetaka koji mogu biti bačeni iz funkcije. Izrada tutorijala 3 T3-1

#include <iostream> #include <vector> using namespace std; bool prost (int n) { for (int i=2;i<n;i++) { if (n%i==0)return false; } return true; } int main() { cout<<"Unesite broj elemenata vaseg vektora->"<<endl; int n; cin>>n; vector<int>a(n); for (int i=0;i<n;i++) { cout<<i+1<<"."; cin>>a[i]; } vector<int>b,c; for (int i=0;i<n;i++)

Page 14: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

{ if ((prost(a[i]))&&(a[i]!=1))b.push_back(a[i]); else { if (a[i]!=1)c.push_back(a[i]); } } cout<<b[0]; for (int i=1;i<b.size();i++) cout<<","<<b[i]; cout<<endl; cout<<c[0]; for (int i=1;i<c.size();i++) cout<<","<<c[i]; return 0; } T3-2 #include <iostream> #include <deque> using namespace std; int main() { int n; cout << "Unesi broj: " << endl; cin>>n; deque<int> a(n),b,c; for(int i=0;i<a.size();i++){ cin>>a[i]; } for(int i=0;i<a.size();i++){ bool prost=true; for(int j=2;j<a[i];j++){ if(a[i]%2==0) prost=false; } if(prost==true) b.push_front(a[i]); else c.push_front(a[i]); } for(int i=0;i<b.size();i++){ cout<<b[i]<<" "; } cout<<endl;

Page 15: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

for(int i=0;i<c.size();i++){ cout<<c[i]<<" "; } return 0; } T3-3 #include <iostream> #include <vector> #include <iomanip> using namespace std; vector<vector<int> > Paskalov (int n) { vector<vector<int> > paskalov(n); for(int i=0;i<n;i++) paskalov[i].resize(i+1); for(int i=0;i<n;i++) {paskalov[i][0]=1; paskalov[i][paskalov[i].size()-1]=1;} for(int i=2;i<n;i++) { for(int j=1;j<paskalov[i].size()-1;j++) {paskalov[i][j]=paskalov[i-1][j-1]+paskalov[i-1][j];} } return paskalov; } int main() { cout<<"Unesite n za koji kreirate Paskalov trougao->"; int n; cin>>n; //kreiranje grbave matrice vector<vector<int> > paskalov; paskalov=Paskalov(n); for(int i=0;i<n;i++) { for( int j=0;j<paskalov[i].size();j++) cout<<setw(7)<<paskalov[i][j]; cout<<endl;}

Page 16: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

return 0; } T3-4 #include <iostream> #include <string> using namespace std; string NadjiRijec(string recenica, int n) { int b(1),j(0); if (recenica[0]==' ') { while (recenica[j]==' ')j++; } string rijec; int pocetak,kraj(0); for (int i=j;i<recenica.size();i++) { if (recenica[i]==' ') { //OVDJE b++; while (recenica[i]==' ')i++; if (b==n) { pocetak=i; while(recenica[i]!=' '){kraj++;i++;} } } } rijec=recenica.substr(pocetak,kraj); return rijec; } int main() { cout << "Unesite vasu recenicu->" << endl; string recenica; getline(cin,recenica); cout<<recenica;

Page 17: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

cout<<"Koju po redu rijec zelite izdvojiti?"<<endl; int m; cin>>m; string rijec; rijec= NadjiRijec(recenica,m); cout<<rijec<<"**"; return 0; } T3-5 #include <iostream> #include <string> using namespace std; string izbaci (string a, int n){ int prvi(a.length()), brojac(0),poc(-1),kraj(-1); bool razmak(true); for(int i=0;i<prvi;i++){ if(a[i]!=' ' && razmak == true){ brojac++; razmak = false; if (brojac == n){ poc=i; } } if (a[i]==' ' && razmak == false) { razmak = true; if (poc != -1) { kraj=i; break; } } } string novi=a.substr(poc,kraj-poc); return novi; } int main() { string rec,a; int n; cout << "Unesi string!" << endl; getline(cin,rec); cout<<"Unesi broj rijeci: "<<endl; cin>>n; a=izbaci(rec,n); cout<<a<<endl; return 0; }

Page 18: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

Zadaci za Tutorial 4. 1. Napišite program koji traži od korisnika da unese spisak riječi (broj riječi se prethodno unosi sa tastature), a zatim ispisuje na ekran prvu i poslednju riječ iz spiska po abecednom poretku, kao i popis svih unesenih riječi, ali bez ispisivanja duplikata (tj. bez ispisivanja riječi koje su se već jednom ispisale). Program realizirajte korištenjem vektora stringova, odnosno vektora čiji su elementi tipa “string ”. Pri tome, nije dozvoljeno sortirati sadržaj vektora. 2. Napišite funkciju “Cifre ” koja treba da ima 3 parametra “n”, “ c min ” i “ c max ”. Funkcija treba da pronađe najmanju i najveću cifru u parametru “n” (koji predstavlja neki prirodan broj), i da smjesti pronađene cifre u parametre “c min ” i “ c max ”. Na primjer, naredba Cifre(37232645, a, b);

treba da u promjenljive “a” i “ b” (pod uvjetom da su propisno deklarirane) smjesti brojeve 2 i 7, jer su upravo to najmanja i najveća cifra u broju 37232645. Funkcija ne smije koristiti nikakve pomoćne nizove ili vektore (samo individualne promjenljive). Napišite i kratki testni program u kojem ćete demonstrirati napisanu funkciju. 3. Napišite funkciju “IzvrniString ” sa jednim parametrom tipa “string ”. Funkcija treba da ispremješta elemente stringa tako da prvi znak postane posljednji, a posljednji prvi. Na primjer, ukoliko se u glavnom programu izvrši sekvenca naredbi string s("Ovo je neki tekst..."); Izvrni(a); cout << s;

ispis na ekranu treba da bude “...tsket iken ej ovO ”. Funkcija treba da bude realizirana tako da vrši premještanje “u mjestu”, odnosno da ne koristi nikakav pomoćni string osim stringa koji je prenesen kao parametar (uputa: razmijenite prvi znak sa posljednjim, drugi sa pretposljednjim, itd.). Napišite i kratki glavni program u kojoj ćete demonstrirati napisanu funkciju na rečenici koja se unosi sa tastature. Oprez: funkcija izvrni ne smije sama po sebi ništa da ispisuje na ekran. Njeno dejstvo treba samo da bude izmjena poretka znakova u stringu, koje će kasnije na ekran ispisati neko drugi (npr. “main ” funkcija). 4. Napišite generičku funkciju “UnosBroja ” sa tri parametra. Funkcija treba da omogući pouzdano unošenje brojeva u program, uz potpunu kontrolu grešaka pri unosu. Prvi i drugi parametar su tipa “string ”. Pri tome, prvi parametar predstavlja tekst koji se ispisuje korisniku kao obavijest da treba unijeti broj (prompt), dok drugi parametar predstavlja tekst koji se ispisuje korisniku kao upozorenje u slučaju da unos nije ispravan. Treći parametar je referenca na proizvoljni numerički tip, a predstavlja promjenljivu u koju će se smjestiti uneseni broj. Na primjer, funkcija se može pozvati na sljedeći način: UnosBroja("Unesi prvi broj: ", "Neispravan unos!\n" , prvi_broj); Funkcija treba da traži unos od korisnika sve dok unos ne bude ispravan. Napisanu funkciju demonstrirajte u testnom programu koji od korisnika traži da unese realni broj x i cijeli broj n, a zatim računa i ispisuje vrijednost stepena xn. 5. Napišite generičku funkciju “Presjek ” koja prima dva parametra “v1 ” i “ v2 ”. Ovi parametri su vektori proizvoljnog ali istog tipa elemenata. Funkcija treba da kao rezultat vrati novi vektor koji se sastoji od elemenata koji se javljaju i u vektoru “v1 ” i u vektoru “v2 ” (drugim riječima, treba formirati presjek skupova čiji su elementi pohranjeni u vektorima “v1 ” i “ v2 ”). Pored toga, u vektoru koji je vraćen kao rezultat iz funkcije svi elementi treba da budu različiti (odnosno, elemente koji se ponavljaju ne treba prepisivati više puta). Poredak brojeva pohranjenih u rezultatu nije bitan. Napisanu funkciju testirajte u testnom programu prvo na dva vektora realnih brojeva, a zatim na dva vektora čiji su elementi stringovi (elementi se unose sa tastature).

Page 19: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

Izrada tutorijala 4. T4-1 #include <iostream> #include <vector> #include <string> using namespace std; int main() { int n; cout << "Unesi broj rijeci: " << endl; cin>>n; vector<string> s(n); for(int i=0;i<n;i++){ cin>>s[i]; } string min(s[0]), max(s[0]); for(int i=0;i<n;i++){ if(s[i]>max) max=s[i]; if(s[i]<min) min=s[i]; bool isti(false); for(int j=0;j<i;j++){ if(s[j]==s[i]) { isti=true; break; } } if(isti==false) cout<<s[i]<<endl; } cout<<"Minimalni je: "<<min<<endl<<"Maksimalni je: "<<max<<endl; return 0; } T4-2 #include <iostream> using namespace std; void MinMaks( int n, int &min, int &maks) { min=9;//jer je to naveca moguca cifra maks=0;//jer je to najmanj moguca cifra int cifra; while(n!=0) { cifra=n%10; if(cifra<min)min=cifra;

Page 20: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

if(cifra>maks)maks=cifra; n=n/10;} } int main() {cout<<"Unesite vas broj->"<<endl; int n; cin>>n; int a(0), b(0); MinMaks(n,a,b); cout<<"Najveca cifra->"<<b; cout<<"Najmanja cifra->"<<a; return 0; } T4-3 #include <iostream> #include <string> using namespace std; void Izvrni(string &recenica) { int i(0),k(recenica.size()-1); while(i!=k) { char pom(recenica[i]); recenica[i]=recenica[k]; recenica[k]=pom; i++;k--; } } int main() { cout<<"Unesite string->"<<endl; string recenica; getline(cin,recenica); Izvrni(recenica); cout<<recenica; return 0; }

Page 21: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

Zadaci za Tutorial 5. 1. Napišite program koji od korisnika traži da sa tastature unese rečenicu, a koji će zatim ispisati unesenu rečenicu bez prve riječi te rečenice. Unesena rečenica se smješta u klasični niz znakova (dakle, ne u promjenljivu tipa “string ”). Za realizaciju zadatka koristiti isključivo pokazivačku aritmetiku. Nije dozvoljena upotreba funkcija iz biblioteka “cstring ” niti “ string ”, kao ni upotreba indeksiranja (uključujući i njegovu trivijalnu simulaciju koja podrazumijeva pisanje “ *(a+n) ” umjesto “a[n] ”). 2. Napišite funkciju sa jednim parametrom n, koja dinamički alocira niz od n cijelih brojeva, popunjava ga sa prvih n stepena broja 2 (stepeni dvojke su redom 1, 2, 4, 8, 16 itd.) i vraća kao rezultat pokazivač na prvi element tako alociranog niza. U slučaju da je n ≤ 0, funkcija treba da baci tekst “Broj elemenata mora biti pozitivan” kao izuzetak, a u slučaju da alokacija ne uspije, funkcija treba da baci tekst “Alokacija nije uspjela” kao izuzetak. Napisanu funkciju iskoristite u testnom programu u kojem se sa tastature unosi broj n, zatim poziva napisana funkcija za kreiranje traženog niza, koji se potom ispisuje na ekran, i na kraju se vrši oslobađanje prostora koji je zauzeo niz. Pored toga, u glavnom programu treba predvidjeti hvatanje svih izuzetaka koji bi funkcija eventualno mogla baciti. 3. Napišite generičku funkciju čiji je parametar vektor elemenata proizvoljnog tipa. Funkcija prvo treba da dinamički kreira niz čiji su elementi istog tipa kao i zadani vektor i koji sadrži isti broj elemenata kao i zadani vektor. Funkcija zatim treba prepisati sve elemente vektora u kreirani niz u obrnutom poretku (tj. prvi element vektora treba da postane posljednji element niza itd.) i vratiti pokazivač na prvi element tako kreiranog niza kao rezultat. Napišite i mali testni program u kojem ćete demonstrirati kako se upotrebljava napisana funkcija na vektoru realnih brojeva čiji se elementi unose sa tastature. 4. Napišite generičku funkciju koja kao svoj parametar prima dvodimenzionalnu strukturu (recimo matricu, ali pri čemu broj elemenata u svakom redu ne mora nužno biti isti) predstavljenu kao vektor vektōrâ čiji su elementi proizvoljnog tipa. Funkcija prvo treba da dinamički alocira prostor za dvodimenzionalnu strukturu identičnog oblika kao i parametar, zatim da u nju prepiše elemente dvodimenzionalne strukture predstavljene parametrom i, konačno, da kao rezultat vrati dvojni pokazivač preko kojeg se može izvršiti pristup elementima ove strukture. U slučaju da dođe do problema sa alokacijom memorije, funkcija treba baciti izuzetak. Pri tome, ni u kom slučaju ne smije doći do curenja memorije. Napisanu funkciju testirati u testnom programu koji sa tastature unosi elemente matrice formata 3 × 3 organizirane kao vektor vektōrâ, a nakon toga poziva napisanu funkciju sa ciljem kreiranja odgovarajuće dinamičke matrice i, konačno, ispisuje elemente tako kreirane dinamičke matrice na ekran i oslobađa zauzetu memoriju. U testnom programu predvidjeti i eventualno hvatanje bačenih izuzetaka. Izrada tutorijala 5. T5-1 #include <iostream> using namespace std; int main() { char recenica[100]; cout << "Unesi recenicu: " << endl; cin.getline(recenica,sizeof recenica); char *p(recenica); bool razmak(true); while(*p!='\0' && *p!='\n') { if(razmak==true && *p!=' ') { razmak=false;

Page 22: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

while(*p!=' ' && *p!='\n') { p++; } p++; } cout<<*p; p++; } return 0; } T5-2 #include <iostream> #include <new> using namespace std; int *StepenBrojaDva (int n) { if(n<=0) throw "Broj elemenata mora biti pozitivan"; int broj(1); int *dinamicki_niz(new int[n]); for (int i=0; i<=n; i++) { dinamicki_niz[i]=broj; broj*=2; } return dinamicki_niz; } int main() { int n; cout << "Unesi broj: " << endl; cin>>n; try {

Page 23: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

int *novi(StepenBrojaDva(n)); for (int i=0; i<=n; i++) { cout<<novi[i]<<endl; } delete[] novi; } catch(const char poruka[]) { cout << poruka; } catch(bad_alloc) { cout <<"Nema dovoljno memorije"; } return 0; } T5-3 #include <iostream> #include <vector> using namespace std; template<typename Tip> Tip *Prepisi (vector<Tip> a) { Tip *dinamicki(new Tip[a.size()]); int e(0); for(int i=a.size()-1; i>=0; i--) { dinamicki[e]=a[i]; e++; } return dinamicki; } int main() { int n; cout << "Unesi broj elemenata: " << endl; cin>>n; vector<double> a(n); for (int i=0; i<n; i++) { cout<<"Unesi "<<i+1<<" elemenat: ";

Page 24: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

cin>>a[i]; } double *pok(Prepisi(a)); for(int i=0; i<n; i++) { cout<<pok[i]<<endl; } return 0; }

Zadaci za Tutorial 6. 1. Postoje razni metodi pomoću kojih je moguće izračunati približnu vrijednost integrala neke funkcije f(x) na intervalu (a, b). Jedan od najjednostavnijih ali ujedno i najmanje tačnih metoda je tzv. trapezno ili Eulerovo pravilo, prema kojem je

gdje je n broj podintervala na koji dijelimo interval (a, b). Veći broj podintervala daje i veću tačnost, ali do određene granice. Napišite funkciju “TrapeznoPravilo ” koja prima kao parametre f, a, b i n ( f je funkcija čiji se integral računa) a koja kao rezultat daje približnu vrijednost integrala računatu pomoću trapeznog pravila. Napisanu funkciju testirajte na primjerima integrala funkcije sin x na intervalu (0, π), zatim funkcije x3 na intervalu (0, 10), i funkcije 1/x na intervalu (1, 2). Testiranje izvršite za različite vrijednosti n i uporedite rezultate sa tačnim rezultatima. Utvrdite kolike su vrijednosti za n bile potrebne da se dobije rezultat tačan na 5 decimala za sva tri primjera. 2a. Napišite program koji traži od korisnika da unese niz rečenica, pri čemu se broj rečenica prethodno unosi sa tastature. Za svaku unesenu rečenicu dinamički alocirajte prostor, uz vođenje evidencije o adresi svake alocirane rečenice u dinamičkom nizu pokazivača na početke svake od rečenica. Nakon toga, treba ispisati unesene rečenice sortirane u abecedni poredak (tačnije rečeno, u rastući poredak po ASCII kodovima). Sortiranje obavite ručno, nekim od jednostavnih postupaka za sortiranje koji Vam je poznat (npr. BubbleSort, SelectionSort, itd.). Drugim riječima, nemojte koristiti gotove funkcije za sortiranje, poput funkcije “sort ” iz biblioteke “algorithm ”. 2b. Izmijenite prethodni program, ali tako što ćete umjesto ručnog sortiranja koristiti funkciju “sort ” iz biblioteke “algorithm ”, uz pogodno definiranu funkciju kriterija. 3. Napišite generičku funkciju “Razmjeni ” koja prihvata iste parametre i obavlja isti zadatak kao funkcija “swap ranges ” iz biblioteke “algorithm ”. Funkciju treba realizirati isključivo korištenjem pokazivačke aritmetike, bez korištenja indeksiranja i njegove trivijalne simulacije (tj. pisanja “*(p+i) ” umjesto “p[i] ”). Napišite i kratki testni program u kojem ćete testirati napisanu funkciju na jednom fiksnom paru nizova cijelih brojeva i na jednom fiksnom paru nizova znakova. 4a. Koristeći odgovarajuće funkcije iz biblioteke “algorithm ”, napišite program koji će za niz cijelih brojeva unesenih sa tastature ispisati: • najveći i najmanji element niza; • koliko puta se u nizu pojavljuje najmanji element; • koliko u nizu cijelih brojeva unesenih sa tastature ima brojeva koji su stepeni dvojke (tj. brojevi poput 1, 2, 4, 8, 16, 32, itd.). Nakon toga, program treba prepisati u drugi niz sve elemente koji nisu stepeni dvojke, i ispisati elemente tako formiranog niza. Napomena: U programu nije uopće dozvoljeno koristiti petlje (osim za unos elemenata niza), već sve manipulacije treba ostvariti isključivo pozivima funkcija iz biblioteke “algorithm ”.

Page 25: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

4b. Izmijenite prethodni program tako što ćete umjesto niza koristiti vektor. 5. Napišite program koji će na primjeru jednog fiksnog sortiranog niza od 50 elemenata i broja “n” unesenog sa tastature ispisati poziciju gdje se broj “ n” nalazi unutar niza, odnosno činjenicu da broj “n” nije pronađen unutar niza. Koristite binarnu pretragu i odgovarajuće funkcije iz biblioteke “algorithm ”.

Zadaci za Tutorial 7. 1. Definirajte strukturu “Vrijeme ” koja sadrži tri polja “sati ”, “ minute ” i “ sekunde ”, i koja predstavlja tekuće vrijeme u toku dana, izraženu u satima, minutama i sekundama. Zatim definirajte funkciju “IspisiVrijeme ” koja ispisuje vrijeme proslijeđeno kao parametar u funkciju u obliku hh:mm:ss (tj. sati, minute i sekunde se ispisuju kao dvocifreni brojevi, eventualno sa vodećim nulama), kao i funkciju “SaberiVrijeme ” koja prima dva vremena kao parametre, i vraća kao rezultat treće vrijeme koje nastaje sabiranjem vremena koja su proslijeđena kao parametri (npr. sabiranjem 3h 34min 52sek i 4h 42min 20sek treba da se dobije vrijeme 8h 17min 12sek). Konačno, napravite mali testni program u kojem ćete testirati napisane funkcije. 2. Prepravite program “ucenici.cpp ” priložen uz Predavanje 7, tako da se umjesto vektora učenika koristi dinamički alociran niz učenika (biblioteku i tip “vector ” nije dozvoljeno koristiti). Upute za ovu prepravku date su na predavanjima. 3. Prepravite program “ucenici_pok.cpp ” priložen uz Predavanje 7, tako da se umjesto vektora pokazivača na učenike koristi dinamički alociran niz pokazivača na učenike učenika (biblioteku i tip “vector ” nije dozvoljeno koristiti). Upute za ovu prepravku date su na predavanjima. 4. Definirajte strukturu “Cvor ” koja sadrži polje “element ” tipa “double ” i polje “veza ” koje je tipa pokazivač na “Cvor ”. Iskoristite ovu strukturu u programu koji čita slijed realnih brojeva sa tastature sve dok se ne unese 0, uvezuje te elemente u povezanu listu čvorova, i na kraju prolazi kroz listu čvorova sa ciljem da prebroji i ispiše koliko ima elemenata u listi koji su veći od aritmetičke sredine svih unesenih elemenata (potrebna su zapravo dva prolaza: prvi za računanje aritmetičke sredine, i drugi za brojanje elemenata sa traženim svojstvom). Izrada tutorijal 7. T7-1

#include <iostream> using namespace std; struct Vrijeme { int sati,minute,sekunde; }; void IspisiVrijeme(const Vrijeme &vrijeme) { cout<<"Vase vrijeme->"<<vrijeme.sati<<":"<<vrijeme.minute<<":"<<vrijeme.sekunde<<endl;

Page 26: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

} Vrijeme SaberiVrijeme(const Vrijeme &prvo, const Vrijeme &drugo) { Vrijeme trece; trece.sati=prvo.sati+drugo.sati; trece.minute=prvo.minute+drugo.minute; trece.sekunde=prvo.sekunde+drugo.sekunde; if (trece.minute>=60) { int sati,minute(trece.minute); sati=minute/60; trece.sati=trece.sati+sati; trece.minute=trece.minute-60*sati; } if (trece.sekunde>=60) { int minute,sekunde(trece.sekunde); minute=sekunde/60; trece.minute=trece.minute+minute; trece.sekunde=trece.sekunde-60*minute; } return trece; } int main() { Vrijeme prvo_vrijeme,drugo_vrijeme,trece_vrijeme; cout<<"Unesite prvo vrijeme->(hh:mm:ss)"; char znak; cin >> prvo_vrijeme.sati >> znak >> prvo_vrijeme.minute >> znak >> prvo_vrijeme.sekunde; cout<<"Unesite drugo vrijeme->(hh:mm:ss)"; cin >> drugo_vrijeme.sati >> znak >> drugo_vrijeme.minute >> znak >> drugo_vrijeme.sekunde; IspisiVrijeme(prvo_vrijeme); IspisiVrijeme(drugo_vrijeme);

Page 27: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

trece_vrijeme=SaberiVrijeme(prvo_vrijeme,drugo_vrijeme); IspisiVrijeme(trece_vrijeme); return 0; } T7-2 #include <iostream> #include <iomanip> #include <string> #include <algorithm> using namespace std; const int BrojPredmeta(12); struct Datum { int dan, mjesec, godina; }; struct Ucenik { string ime, prezime; Datum datum_rodjenja; int ocjene[BrojPredmeta]; double prosjek; bool prolaz; }; int main() { void UnesiUcenike(Ucenik *ucenici, int broj_ucenika); void ObradiUcenike(Ucenik *ucenici,int broj_ucenika); void IspisiIzvjestaj(Ucenik*ucenici,int broj_ucenika); int broj_ucenika; cout << "Koliko ima ucenika: "; cin >> broj_ucenika; Ucenik *ucenici; try { ucenici=new Ucenik[broj_ucenika]; UnesiUcenike(ucenici,broj_ucenika); ObradiUcenike(ucenici,broj_ucenika); IspisiIzvjestaj(ucenici,broj_ucenika); } catch(...) { cout << "Problemi sa memorijom...\n";

Page 28: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

} return 0; } void UnesiUcenike(Ucenik *ucenici,int broj_ucenika) { void UnesiJednogUcenika(Ucenik &ucenik); for(int i = 0; i < broj_ucenika; i++) { cout << "Unesite podatke za " << i + 1 << ". ucenika:\n"; UnesiJednogUcenika(ucenici[i]); } } void UnesiJednogUcenika(Ucenik &ucenik) { void UnesiDatum(Datum &datum); void UnesiOcjene(int ocjene[], int broj_predmeta); cout << " Ime: "; cin >> ucenik.ime; cout << " Prezime: "; cin >> ucenik.prezime; cout << " Datum rodjenja (D/M/G): "; UnesiDatum(ucenik.datum_rodjenja); UnesiOcjene(ucenik.ocjene, BrojPredmeta); } void UnesiDatum(Datum &datum) { char znak; cin >> datum.dan >> znak >> datum.mjesec >> znak >> datum.godina>>znak; } void UnesiOcjene(int ocjene[], int broj_predmeta) { for(int i = 0; i < broj_predmeta; i++) { cout << " Ocjena iz " << i + 1 << ". predmeta: "; cin >> ocjene[i]; } } void ObradiUcenike(Ucenik *ucenici, int broj_ucenika) { void ObradiJednogUcenika(Ucenik &ucenik); bool DaLiJeBoljiProsjek(const Ucenik &u1, const Ucenik &u2); for(int i = 0; i < broj_ucenika; i++) ObradiJednogUcenika(ucenici[i]); sort(ucenici, ucenici+broj_ucenika, DaLiJeBoljiProsjek); } void ObradiJednogUcenika(Ucenik &ucenik) { double suma_ocjena(0);

Page 29: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

ucenik.prosjek = 1; ucenik.prolaz = false; for(int i = 0; i < BrojPredmeta; i++) { if(ucenik.ocjene[i] == 1) return; suma_ocjena += ucenik.ocjene[i]; } ucenik.prolaz = true; ucenik.prosjek = suma_ocjena / BrojPredmeta; } bool DaLiJeBoljiProsjek(const Ucenik &u1, const Ucenik &u2) { return u1.prosjek > u2.prosjek; } void IspisiIzvjestaj(Ucenik *ucenici, int broj_ucenika) { void IspisiJednogUcenika(const Ucenik &ucenik); cout << endl; for(int i = 0; i < broj_ucenika; i++) IspisiJednogUcenika(ucenici[i]); } void IspisiJednogUcenika(const Ucenik &ucenik) { void IspisiDatum(const Datum &datum); cout << "Ucenik " << ucenik.ime << " " << ucenik.prezime << " rodjen "; IspisiDatum(ucenik.datum_rodjenja); if(ucenik.prolaz) cout << " ima prosjek " << setprecision(3) << ucenik.prosjek; else cout << " mora ponavljati razred"; cout << endl; } void IspisiDatum(const Datum &datum) { cout << datum.dan << "." << datum.mjesec << "." << datum.godina; } T7-3 #include <iostream> #include <iomanip> #include <string> #include <algorithm> using namespace std; const int BrojPredmeta(2); //dinamički niz pokazivača na strukture tipa “Ucenik”,

Page 30: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

struct Datum { int dan, mjesec, godina; }; struct Ucenik { string ime, prezime; Datum datum_rodjenja; int ocjene[BrojPredmeta]; double prosjek; bool prolaz; }; int main() { void UnesiUcenike(Ucenik **ucenici, int broj_ucenika); void ObradiUcenike(Ucenik**ucenici,int broj_ucenika); void IspisiIzvjestaj(Ucenik**ucenici,int broj_ucenika); void OslobodiMemoriju(Ucenik**ucenici,int broj_ucenika); int broj_ucenika; cout << "Koliko ima ucenika: "; cin >> broj_ucenika; Ucenik **ucenici; try { ucenici=new Ucenik*[broj_ucenika]; UnesiUcenike(ucenici,broj_ucenika); ObradiUcenike(ucenici,broj_ucenika); IspisiIzvjestaj(ucenici,broj_ucenika); } catch (...) { cout << "Problemi sa memorijom...\n"; } //Inicijalizacija pokazivaca na nulu for(int i=0;i<broj_ucenika;i++) ucenici[i]=0; OslobodiMemoriju(ucenici,broj_ucenika); delete []ucenici;

Page 31: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

return 0; } void UnesiUcenike(Ucenik**ucenici,int broj_ucenika) { void UnesiJednogUcenika(Ucenik *ucenik); for (int i = 0; i < broj_ucenika; i++) { cout << "Unesite podatke za " << i + 1 << ". ucenika:\n"; ucenici[i] = new Ucenik; UnesiJednogUcenika(ucenici[i]); } } void UnesiJednogUcenika(Ucenik *ucenik) { void UnesiDatum(Datum &datum); void UnesiOcjene(int ocjene[], int broj_predmeta); cout << " Ime: "; cin >> ucenik->ime; cout << " Prezime: "; cin >> ucenik->prezime; cout << " Datum rodjenja (D/M/G) : "; UnesiDatum(ucenik->datum_rodjenja); UnesiOcjene(ucenik->ocjene, BrojPredmeta); } void UnesiDatum(Datum &datum) { char znak; cin >> datum.dan >> znak >> datum.mjesec >> znak >> datum.godina>>znak; } void UnesiOcjene(int ocjene[], int broj_predmeta) { for (int i = 0; i < broj_predmeta; i++) { cout << " Ocjena iz " << i + 1 << ". predmeta: "; cin >> ocjene[i]; } } void ObradiUcenike(Ucenik**ucenici,int broj_ucenika) {

Page 32: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

void ObradiJednogUcenika(Ucenik *ucenik); bool DaLiJeBoljiProsjek(const Ucenik *u1, const Ucenik *u2); for (int i = 0; i < broj_ucenika; i++) ObradiJednogUcenika(ucenici[i]); sort(ucenici, ucenici+broj_ucenika, DaLiJeBoljiProsjek); } void ObradiJednogUcenika(Ucenik *ucenik) { double suma_ocjena(0); ucenik->prosjek = 1; ucenik->prolaz = false; for (int i = 0; i < BrojPredmeta; i++) { if (ucenik->ocjene[i] == 1) return; suma_ocjena += ucenik->ocjene[i]; } ucenik->prolaz = true; ucenik->prosjek = suma_ocjena / BrojPredmeta; } bool DaLiJeBoljiProsjek(const Ucenik *u1, const Ucenik *u2) { return u1->prosjek > u2->prosjek; } void IspisiIzvjestaj(Ucenik**ucenici,int broj_ucenika) { void IspisiJednogUcenika(const Ucenik *ucenik); cout << endl; for (int i = 0; i < broj_ucenika; i++) IspisiJednogUcenika(ucenici[i]); } void IspisiJednogUcenika(const Ucenik *ucenik) { void IspisiDatum(const Datum &datum); cout << "Ucenik " << ucenik->ime << " " << ucenik->prezime << " rodjen "; IspisiDatum(ucenik->datum_rodjenja); if (ucenik->prolaz) cout << " ima prosjek " << setprecision(3) << ucenik->prosjek; else cout << " mora ponavljati razred"; cout << endl;

Page 33: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

} void IspisiDatum(const Datum &datum) { cout << datum.dan << "." << datum.mjesec << "." << datum.godina; } void OslobodiMemoriju(Ucenik**ucenici,int broj_ucenika) { for (int i = 0; i < broj_ucenika; i++) delete ucenici[i]; } T7-4 #include <iostream> using namespace std; struct Cvor{ double elemenat; Cvor *sljedeci; }; int main() { Cvor *prvi(0),*zadnji; for(;;){ double broj; cin>>broj; if(broj==0)break; Cvor*novi=new Cvor; novi->elemenat=broj; novi->sljedeci=0; if(prvi!=0)zadnji->sljedeci=novi; else prvi =novi; zadnji=novi; } double aritmetickaSredina(0); int broj(0); for(Cvor*p=prvi;p!=0;p=p->sljedeci) { aritmetickaSredina=aritmetickaSredina+p->elemenat; broj++; }

Page 34: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

aritmetickaSredina=aritmetickaSredina/broj; int brojevaVecihOdAritmetickeSredine(0); for(Cvor*p=prvi;p!=0;p=p->sljedeci) { if(p->elemenat>aritmetickaSredina) { cout<<p->elemenat<<endl; brojevaVecihOdAritmetickeSredine++;}} cout<<"Brojeva u linkovanoj listi vecih od aritmeticke sredine je ->"<<brojevaVecihOdAritmetickeSredine<<endl; return 0; } T7-4-drugi nacin pisanja pokazivaca #include <iostream> using namespace std; struct Cvor{ double elemenat; Cvor *sljedeci; }; int main() { Cvor *prvi(0),*zadnji; for(;;){ double broj; cin>>broj; if(broj==0)break; Cvor*novi=new Cvor; (*novi).sljedeci=0; if(prvi!=0)(*zadnji).sljedeci=novi; else prvi =novi; zadnji=novi; } double aritmetickaSredina(0); int broj(0); for(Cvor*p=prvi;p!=0;p=(*p).sljedeci) { aritmetickaSredina=aritmetickaSredina+p->elemenat; broj++;

Page 35: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

} aritmetickaSredina=aritmetickaSredina/broj; int brojevaVecihOdAritmetickeSredine(0); for(Cvor*p=prvi;p!=0;p=(*p).sljedeci) { if(p->elemenat>aritmetickaSredina) { cout<<p->elemenat<<endl; brojevaVecihOdAritmetickeSredine++;}} cout<<"Brojeva u linkovanoj listi vecih od aritmeticke sredine je ->"<<brojevaVecihOdAritmetickeSredine<<endl; for(Cvor*p=prvi;p!=0;p=(*p).sljedeci) delete p; return 0; }

Zadaci za Tutorial 8. 1. Definirajte i implementirajte klasu “Vektor3d” u skladu sa deklaracijom i implementacijom prikazanom pred kraj Predavanja 8, s tim što ćete dodati još tri nove metode “PostaviX”, “PostaviY” i “ PostaviZ” koje treba da omoguće neovisnu izmjenu pojedinačnih koordinata vektora. Napišite i mali testni program u kojem ćete demonstrirati sve elemente razvijene klase. 2. Izmijenite implementaciju klase razvijene u prethodnom zadatku tako da se za čuvanje koordinata vektora umjesto tri privatna atributa “x”, “ y” i “ z” koji su tipa realnih brojeva koristi jedan privatni atribut “koordinate” koji je tipa niza od tri realna elementa. Izmjenu treba izvesti tako da zaglavlja svih metoda unutar interfejsa klase ostanu neizmijenjena. Demonstrirajte da će testni program napisan u prethodnom zadatku raditi bez ikakvih izmjena sa ovako izmijenjenom klasom. 3. Definirajte i implementirajte klasu “Sat” koja predstavlja digitalni sat. Klasa treba da ima sljedeći interfejs: void Postavi(int sati, int minute, int sekunde); void Sljedeći(); void Prethodni(); void PomjeriZa(int pomak); int DajSate() const ; int DajMinute() const ; int DajSekunde() const ; void Ispisi() const ; Metoda “Postavi” omogućava postavljanje sata na zadani iznos sati, minuta i sekundi. Ova metoda baca izuzetak ukoliko se proslijede neispravni parametri. Metoda “Sljedeci” treba da poveća vrijeme zapamćeno u satu za 1 sekundu (npr. ukoliko je tekuće vrijeme “12:48:59”, nakon poziva ove metode vrijeme treba da postane “12:49:00”). Slično, metoda “Prethodni” treba da smanji vrijeme zapamćeno u satu za 1 sekundu, dok metoda “PomjeriZa” predstavlja generalizaciju prethodne dvije metode tako što vrši pomak tekućeg vremena za broj sekundi koji je zadan parametrom “pomak” (pomjeranje je unazad ukoliko se proslijedi negativna vrijednost kao parametar). Metoda “Ispisi” treba da ispiše stanje sata u obliku “hh : mm: ss”. Metode “DajSate”, “ DajMinute” i “ DajSekunde” vraćaju trenutni broj sati, minuta i sekundi u tekućem vremenu. Kao atribute klase uzmite trenutni broj sati, minuta i sekundi, koje ćete

Page 36: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

definirati kao privatne atribute. Obavezno napišite i testni program u kojem će se upotrebiti svi elementi interfejsa napisane klase. Uputa: Metode “Sljedeci” i “ Prethodni” mogu se realizirati pozivom metode “PomjeriZa”, s obzirom da su one njen specijalni slučaj. 4. Definirajte i implementirajte klasu “Sat” koja ima potpuno isti interfejs i potpuno isto ponašanje kao klasa iz prethodnog zadatka, samo čija se interna struktura umjesto tri atributa koja čuvaju trenutni broj sati, minuta i sekundi sastoji samo od jednog atributa, koji čuva ukupan broj sekundi (npr. umjesto informacije “3 sata, 20 minuta, 15 sekundi” čuva se samo informacija koja kaže 12015 sekundi). Mada će ovo tražiti izmjenu implementacije svih (ili skoro svih) metoda klase (konstruktori i metoda “Postavi” će se sasvim neznatno izmijeniti, metode “Sljedeci”, “Prethodni” i “ PomjeriZa” će se bitno pojednostaviti, dok će se metode “DajSate”, “DajMinute”, “ DajSekunde” i možda metoda “Ispisi” zakomplicirati), pokažite da će testni program iz prethodnog zadatka bez ikakve prepravke raditi sa ovako modificiranom klasom. Izrada tutorijala 8. T8-1 i 2

#include <iostream> #include <cmath> using namespace std; class Vektor3d { double koordinate[3]; public: void Postavi(double x, double y, double z) { koordinate[0] = x; koordinate[1] = y; koordinate[2] = z; } void Ocitaj(double &x, double &y, double &z) const { x = koordinate[0]; y = koordinate[1]; z = koordinate[2]; } void Ispisi() const { cout << "{" << koordinate[0]<< "," << koordinate[1]<< "," << koordinate[2]<< "}"; } double DajX() const { return koordinate[0]; } double DajY() const {

Page 37: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

return koordinate[1]; } double DajZ() const { return koordinate[2]; } double DajDuzinu() const { return sqrt(koordinate[0]* koordinate[0] + koordinate[1]* koordinate[1] + koordinate[2] * koordinate[2]); } void PomnoziSaSkalarom(double s) { koordinate[0]*= s; koordinate[1]*= s; koordinate[2]*= s; } friend void operator+=( Vektor3d &v,const Vektor3d &v2); /* void SaberiSa(const Vektor3d &v) { koordinate[0]+= v.koordinate[0]; koordinate[1]+= v.koordinate[1]; koordinate[2]+= v.koordinate[2]; }*/ void PostaviX( double x) { koordinate[0]=x; } void PostaviY( double y) { koordinate[1]=y; } void PostaviZ( double z) { koordinate[2]=z; } };

Page 38: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

void operator+=( Vektor3d &v,const Vektor3d &v2) {v.koordinate[0]+= v2.koordinate[0]; v.koordinate[1]+= v2.koordinate[1]; v.koordinate[2]+= v2.koordinate[2];} int main() { Vektor3d vektor,vektor2; vektor.Postavi(2,3,4); vektor.Ispisi();cout<<endl; vektor.PostaviX(6); vektor.Ispisi(); cout<<vektor.DajX(); vektor2.Postavi(4,5,6); vektor2.Ispisi();cout<<endl; vektor+=vektor2; vektor.Ispisi(); return 0; } T8-3 #include <iostream> using namespace std; class Sat {//atributi int sati, minute,sekunde; public: //inline funkcija void Postavi(int sati, int minute, int sekunde) { if (sati<0||sati>24||minute>60||minute<0||sekunde>60||sekunde<0) throw "Neispravan unos"; Sat::sati=sati; Sat::minute=minute; Sat::sekunde=sekunde;

Page 39: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

// this->sati=sati (jos jedna mogucnost da izbjegnemo name clash) } //Funkcije koje implementiramo direktno unutar klase su po defaultu inline (umetnute funkcije) //prototipovi metoda void Sljedeci(); void Prethodni(); void PomjeriZa(int pomak); //const funkcije koje samo ispisuju, ne mogu se mijenjati atributi kroz njih int DajSate() const { return sati; } int DajMinute() const { return minute; } int DajSekunde() const { return sekunde; } void Ispisi() const { cout<<"Sati->"<<sati<<endl<<"Minute->"<<minute<<endl<<"Sekunde->"<<sekunde<<endl; } }; // ";" -OBAVEZNO STAVITI void Sat::Sljedeci() { sekunde=sekunde+1; if (sekunde >=60) { minute ++; sekunde=0; } if (minute>=60) {

Page 40: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

sati++; minute=0; } if (sati==24)sati=0; } //86400 je broj sekundijednog dana void Sat::Prethodni() { sekunde--; if (sekunde <0) { minute --; sekunde=59; } if (minute<0) { sati--; minute = 59; } if (sati<0)sati=23; } void Sat:: PomjeriZa(int pomak) { pomak+=sati*3600+minute*60+sekunde; pomak=pomak%86400; if (pomak<0) { pomak+=86000; } sati = pomak/3600; pomak=pomak%3600; minute = pomak/60; pomak = pomak%60; sekunde = pomak; } /* int main(){

Page 41: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

.... Sat Sada; Sada.Postavi(12,12,12) inline funkcija Sada.PomakZa(10); 1-enkapsulacija(funkcionalsnot objekta enkapsuliramo u funkcije, korisniku stvaramo interfejs, mi kreiramo pravila igre, nema malverzacije nad podacima) 2-sakrivanje podataka(private, publi, protected) 3-nasljedjivanje 4-polimorfizam */ int main() {//verzija kojom mozemo provjeriti sve metode Sat trenutno; int sati, minute,sekunde; cout<<"Unesite sate->"; cin>>sati; cout<<"minute->"; cin>>minute; cout<<"sekunde->"; cin>>sekunde; trenutno.Postavi(sati,minute,sekunde); trenutno.Ispisi(); cout<<"Unesite pomak->"<<endl; int pomak; cin>>pomak; trenutno.PomjeriZa(pomak); trenutno.Ispisi();cout<<endl; trenutno.Sljedeci(); trenutno.Ispisi();cout<<endl; return 0; } T8-3-druga verzija #include <iostream> using namespace std;

Page 42: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

class Sat { int sati; int minute; int sekunde; public: void Postavi(int sati, int minute, int sekunde) { this->sati = sati; this->minute = minute; this->sekunde = sekunde; } void Sljedeci(); void Prethodni(); void PomjeriZa(int pomak); int DajSate() const { return sati; } int DajMinute() const { return minute; } int DajSekunde() const { return sekunde; } void Ispisi() const { if (sati < 10) cout << "0"; cout << sati << ":"; if (minute < 10) cout << "0"; cout << minute << ":"; if (sekunde < 10) cout << "0"; cout << sekunde << endl; } }; void Sat::Sljedeci() { sekunde++; if (sekunde == 60) { sekunde = 0;

Page 43: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

minute++; } if (minute == 60) { minute = 0; sati++; } if (sati == 24) sati = 0; } void Sat::Prethodni() { sekunde--; if (sekunde == -1) { sekunde = 59; minute--; } if (minute == -1) { minute = 59; sati--; } if (sati == -1) { sati = 23; } } void Sat::PomjeriZa(int pomak) { pomak += sati * 3600 + minute * 60 + sekunde; pomak %= 86400; if (pomak < 0) pomak += 86400; sati = pomak / 3600; pomak %= 3600; minute = pomak / 60; pomak %= 60; sekunde = pomak; } int main() { Sat sada; sada.Postavi(10, 8, 13); sada.Ispisi();

Page 44: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

sada.Sljedeci(); sada.Ispisi(); sada.Prethodni(); sada.Ispisi(); sada.PomjeriZa(86400); sada.Ispisi(); sada.PomjeriZa(-86400); sada.Ispisi(); return 0; } T8-4 #include <iostream> using namespace std; class Sat { int sekunde; public: void Postavi (int sek); void Sljedeci() { sekunde++; } void Prethodni() { sekunde--; } void Pomjeri (int pomak) { sekunde+=pomak; } /*int DajSate () const { return sati; } int Dajminutee () const { return minute; } int DajSekunde () const { return sekunde; } zavrsiti!!! */ void Ispisi() const; }; int main() { try{ int a,broj; Sat digitalni; cout << "Unesi broj sekundi: "<<endl; cin>>a; digitalni.Postavi(a); cout<<"Uneseno vrijeme je: "; digitalni.Ispisi(); digitalni.Sljedeci(); cout<<"\nVrijeme pomjereno za 1 sekundu od unesenog vremena je: "; digitalni.Ispisi(); cout<<endl; cout<<"Unesi broj sekundi za koje zelite pomjeriti vrijeme: "; cin>>broj; digitalni.Pomjeri(broj); cout<<endl; digitalni.Ispisi(); cout<<"\nVrijeme pomjereno 1 sekundu unazad ima: "; digitalni.Prethodni(); digitalni.Ispisi();

Page 45: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

} catch(const char poruka[]){ cout<<poruka<<endl; } return 0; } void Sat::Postavi(int sek){ { if(sek<0) throw "Pogresni parametri"; Sat::sekunde=sek; }} void Sat::Ispisi() const { int sati(0), minute(0), pom(sekunde); sati=pom/3600; pom-=sati*3600; if(sati==0) { cout<<"(00,"; } else cout<<"("<<sati; minute=pom/60; pom-=minute*60; if(minute==0) { cout<<"00,"; } else cout<<","<<minute<<","; if(pom==0) { cout<<"00)"; } else cout<<pom<<")"; }

Zadaci za Tutorial 9. 1. Definirajte i implementirajte klasu “Ugao” (ili “ Kut ”, u skladu sa Vašim jezičkim opredjeljenjem) koja omogućava rad sa uglovima (kutovima) u ravni. Klasa treba da ima sljedeći interfejs: void Postavi( double radijani); void Postavi( int stepeni, int minute, int sekunde); double DajRadijane() const ; void OcitajKlasicneJedinice( int &stepeni, int &minute, int &sekunde); int DajStepene() const ; int DajMinute() const ; int DajSekunde() const ; void Ispisi() const ; void IspisiKlasicno() const ; Ugao &SaberiSa( const Ugao &u); Ugao &PomnoziSa( double x); friend Ugao ZbirUglova( const Ugao &u1, const Ugao &u2); friend Ugao ProduktUglaSaBrojem( const Ugao &u, double x);

Prva verzija metode “Postavi ” postavlja vrijednost ugla u radijanima, dok druga verzija metode “Postavi ” postavlja vrijednost ugla u stepenima, minutama i sekundama. Pri tome se svi uglovi reduciraju na opseg od 0 do 2π odnosno od 0 do 360 ° tako da se, na primjer, ugao od 5π/2 odnosno 450 ° automatski reducira na vrijednost π/2 odnosno 90 °, dok se ugao od –π/4 odnosno – 45 ° automatski reducira na vrijednost 315 ° odnosno 7π/4. Metoda “DajRadijane ”

Page 46: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

vraća vrijednost ugla u radijanima. Metoda “OcitajKlasicneJedinice ” očitava vrijednost ugla u stepenima, minutama i sekundama i smješta očitane vrijednosti u odgovarajuće parametre metode. Metode “DajStepene ”, “ DajMinute ” i “ DajSekunde ” omogućavaju da se istim ovim informacijama pristupi neovisno, a ne isključivo “u paketu”. Metoda “Ispisi ” ispisuje vrijednost ugla u radijanima, dok metoda “IspisiKlasicno ” ispisuje vrijednost ugla u stepenima, minutama i sekundama u obliku poput “23deg 8min 47sec”. Metoda “SaberiSa ” dodaje ugao zadan parametrom na ugao nad kojim je primijenjena i usput vraća kao rezultat tako modificiran ugao. Metoda “PomnoziSa ” množi ugao nad kojim je primijenjena sa brojem koji je zadan parametrom i usput vraća kao rezultat tako modificiran ugao. Obje ove metode trebaju obezbijediti da nakon izvršene operacije rezultat bude reduciran na opseg 0 – 2π (0 – 360 °). Konačno, prijateljske funkcije “ZbirUglova ” i “ ProduktUglaSaBrojem ” vraćaju kao rezultat novi ugao koji je jednak zbiru uglova zadanih parametrima, odnosno produktu ugla i broja koji su zadani putem parametara. Implementaciju klase treba zasnovati na jednom privatnom atributu koji čuva vrijednost ugla u radijanima (realan broj). Napišite i kratki testni program u kojem ćete demonstrirati da svi elementi napisane klase rade u skladu sa specifikacijama. 2. Izmijenite implementaciju klase razvijene u prethodnom zadatku tako da se informacija o uglu umjesto u radijanima interno čuva u tri cjelobrojna atributa koji redom sadrže broj stepeni, minuta i sekundi koje čine ugao. Iako će ova izmjena tražiti promjenu implementacije gotovo svih metoda klase, uvjerite se da će nakon te izmjene testni program koji koristi napisanu klasu i dalje raditi posve identično, bez ikakvih izmjena. Izrada tutorijala 9. T9-1 #include<iostream> const double PI=3.14159265; using namespace std; class Ugao{ double rad; void Pretvori (double &n){ double stepen(n*180/PI); if(stepen>360){ while(stepen>360) stepen-=360; } if(stepen<0){ int k(((int)stepen/360)+1); stepen=360*k-stepen; } n=stepen*PI/180; } public: void Postavi(double radijani) { Pretvori(radijani); Ugao::rad=radijani; } void Postavi(int stepeni, int minute, int sekunde){ double stepen=stepeni+minute/60.+sekunde/3600.; Ugao::rad=(stepen*PI)/180; } double DajRadijane() const { return rad; } void OcitajKlasicneJedinice(int &stepeni, int &minute, int &sekunde); int DajStepene() const { return rad*180/PI; }

Page 47: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

int DajMinute() const { return (DajRadijane()*180/PI-DajStepene())*60; } int DajSekunde() const; void Ispisi() const; void IspisiKlasicno() const; Ugao &SaberiSa(const Ugao &u); Ugao &PomnoziSa(double x); friend Ugao ZbirUglova(const Ugao &u1, const Ugao &u2); friend Ugao ProduktUglaSaBrojem(const Ugao &u, double x); }; int main(){ Ugao proba; int step(0), min(0), sek(0); double rad, mnozi; cout<<"Unesi ugao u radijanima: "; cin>>rad; proba.Postavi(rad); cout<<"Uneseni ugao ima: "<<proba.DajRadijane()<<endl; proba.Ispisi(); cout<<endl; proba.IspisiKlasicno(); cout<<endl; proba.OcitajKlasicneJedinice(step, min, sek); cout<<step<<" "<<min<<" "<<sek<<endl; cout<<"Unesi broj za mnozenje: "; cin>>mnozi; proba.PomnoziSa(mnozi); cout<<proba.DajRadijane()<<endl; proba.Ispisi(); cout<<endl; proba.IspisiKlasicno(); cout<<endl; return 0; } void Ugao::OcitajKlasicneJedinice (int &stepeni, int &minute, int &sekunde){ stepeni=DajStepene(); minute=DajMinute(); sekunde=DajSekunde(); } void Ugao::Ispisi() const { cout<<"Uneseni ugao u radijanima je: "<<DajRadijane()<<"rad.\n"; } void Ugao::IspisiKlasicno() const {

Page 48: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

cout<<"Uneseni ugao ima: "<<DajStepene()<<"deg, "<<DajMinute()<<"min, "<<DajSekunde()<<"sek.\n"; } int Ugao::DajSekunde() const{ double sekunde(rad*180/PI-DajStepene()); sekunde*=60; sekunde-=DajMinute(); sekunde*=60; return sekunde; } Ugao& Ugao::SaberiSa(const Ugao &u){ double pom(rad); pom+=u.rad; Pretvori(pom); rad=pom; return *this; } Ugao& Ugao::PomnoziSa(double x){ double pom(rad); pom*=x; Pretvori(pom); rad=pom; return *this; } Ugao ZbirUglova(const Ugao &u1, const Ugao &u2) { Ugao u3; u3.rad=u1.rad+u2.rad; return u3; } Ugao ProduktUglaSaBrojem(const Ugao &u, double x){ Ugao pom; pom.rad=u.rad*x; return pom; } T9-2 #include<iostream> const double PI=3.14159265; using namespace std; class Ugao{ double stepeni, minute, sekunde; void SmanjiUgao (double &pom){

Page 49: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

if(pom>360){ while(pom>360) pom-=360; } if(pom<0){ int k(((int)pom/360)+1); pom=360*k-pom; } } public: void Postavi(double radijani); void Postavi(int stepeni, int minute, int sekunde){ Ugao::stepeni=stepeni; Ugao::minute=minute; Ugao::sekunde=sekunde; } double DajRadijane() const { return (stepeni+minute/60.+sekunde/3600.)*PI/180; } void OcitajKlasicneJedinice(int &stepeni, int &minute, int &sekunde); int DajStepene() const { return stepeni; } int DajMinute() const { return minute; } int DajSekunde() const { return sekunde; } void Ispisi() const; void IspisiKlasicno() const; Ugao &SaberiSa(const Ugao &u); Ugao &PomnoziSa(double x); friend Ugao ZbirUglova(const Ugao &u1, const Ugao &u2); friend Ugao ProduktUglaSaBrojem(const Ugao &u, double x); }; int main(){ Ugao proba; int step, min, sek; double rad, mnozi; cout<<"Unesi ugao: "; cout<<"Unesi broj stepeni: "; cin>>step; cout<<"Unesi broj minuta: "; cin>>min; cout<<"Unesi broj sekundi: "; cin>>sek; proba.Postavi(step, min, sek); cout<<"Uneseni ugao ima: "<<proba.DajRadijane()<<endl; proba.Ispisi(); cout<<endl; proba.IspisiKlasicno(); cout<<endl; proba.OcitajKlasicneJedinice(step, min, sek); cout<<step<<" "<<min<<" "<<sek<<endl;

Page 50: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

cout<<"Unesi broj za mnozenje: "; cin>>mnozi; proba.PomnoziSa(mnozi); cout<<proba.DajRadijane()<<endl; proba.Ispisi(); cout<<endl; proba.IspisiKlasicno(); cout<<endl; return 0; } void Ugao::Postavi(double radijani){ double pomocni(radijani*180/PI); SmanjiUgao(pomocni); stepeni=static_cast<int>(pomocni); pomocni-=stepeni; pomocni*=60; minute=static_cast<int>(pomocni); pomocni-=minute; pomocni*=60; sekunde=static_cast<int>(pomocni); } void Ugao::OcitajKlasicneJedinice (int &stepeni, int &minute, int &sekunde){ stepeni=stepeni; minute=minute; sekunde=sekunde; } void Ugao::Ispisi() const { cout<<"Uneseni ugao u radijanima je: "<<DajRadijane()<<"rad.\n"; } void Ugao::IspisiKlasicno() const { cout<<"Uneseni ugao ima: "<<DajStepene()<<"deg, "<<DajMinute()<<"min, "<<DajSekunde()<<"sek.\n"; } Ugao& Ugao::SaberiSa(const Ugao &u){ double pomocni(stepeni+u.stepeni+(minute+u.minute)/60.+(sekunde+u.sekunde)/3600.); SmanjiUgao(pomocni); stepeni=static_cast<int>(pomocni); pomocni-=stepeni; pomocni*=60; minute=static_cast<int>(pomocni); pomocni-=minute; pomocni*=60; sekunde=static_cast<int>(pomocni); return *this; }

Page 51: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

Ugao& Ugao::PomnoziSa(double x){ double pomocni(stepeni+minute/60.+sekunde/3600.*PI/180); pomocni*=x; SmanjiUgao(pomocni); stepeni=static_cast<int>(pomocni); pomocni-=stepeni; pomocni*=60; minute=static_cast<int>(pomocni); pomocni-=minute; pomocni*=60; sekunde=static_cast<int>(pomocni); return *this; } /*Ugao ZbirUglova(const Ugao &u1, const Ugao &u2) { Ugao u3; u3.rad=u1.rad+u2.rad; return u3; } Ugao ProduktUglaSaBrojem(const Ugao &u, double x){ Ugao pom; pom.rad=u.rad*x; return pom; } */

Zadaci za Tutorial 10. 1. Definirajte i implementirajte klasu “Tim ” koja predstavlja jedan tim u fudbalskom prvenstvu, sa privatnim atributima “ime ”, “ broj odigranih ”, “ broj pobjeda ”, “ broj nerijesenih ”, “broj poraza ”, “ broj datih ”, “ broj primljenih ” i “ broj poena ” koji sadrže redom naziv tima (do 20 znakova), broj odigranih utakmica, broj pobjeda, broj neriješenih utakmica, broj poraza, ukupan broj datih i primljenih golova, kao i broj poena za razmatrani tim. Atribut “ ime ” treba izvesti kao klasični niz znakova. Klasa treba da ima sljedeći interfejs: Tim( const char ime[]); void ObradiUtakmicu( int broj datih, int broj primljenih); const char *DajImeTima() const ; int DajBrojPoena() const ; int DajGolRazliku() const ; void IspisiPodatke() const ; Konstruktor treba da postavi ime tima na vrijednost zadanu parametrom, a sve ostale atribute klase na nulu. Metoda “ObradiUtakmicu ” treba da na osnovu rezultata utakmice koji joj se prenosi kao parametar (u vidu broja datih i primljenih golova sa posmatrane utakmice) ažurira ne samo atribute koje broje golove, nego i atribute koji broje odigrane utakmice, broj pobjeda, poraza i neriješenih utakmica, kao i broj bodova. Pri tome se za pobjedu dodjeljuju 3 boda, za neriješen rezultat 1 bod, dok se za poraz ne dodjeljuju bodovi. Metode “DajImeTima ”, “DajBrojPoena ” i “ DajGolRazliku ” treba da vrate respektivno ime tima (tačnije, pokazivač na prvi znak imena), broj poena, kao i gol razliku (tj. razliku između ukupnog broja datih i primljenih golova) za posmatrani tim (ove metode implementirati unutar deklaracije klase). Konačno, metoda “IspisiPodatke ” treba da ispiše na ekran sve podatke o timu u jednom redu, i to sljedećim redom: ime tima, broj utakmica, broj pobjeda, broj neriješenih utakmica, broj poraza, broj datih golova, broj primljenih golova i broj poena. Pri ispisu, za ime tima zauzmite prostor od 20 znakova, u kojem ime treba da bude ispisano poravnato ulijevo, a za sve

Page 52: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

brojne podatke prostor od 4 znaka na ekranu, pri čemu ispis svakog brojčanog podatka treba biti poravnat udesno unutar predviđenog prostora. Napišite i kratki testni program u kojem ćete demonstrirati napisanu klasu. 2. Napišite klasu “Liga ” koja se oslanja na prethodno napisanu klasu “Tim ”. Klasa treba da ima privatne atribute “broj_timova ” i “ max_br_timova ” koji čuvaju redom broj timova odnosno maksimalni dozvoljeni broj timova u ligi (atribut “max_br_timova ” treba da bude konstantni atribut), kao i privatni atribut “timovi ” koji će služiti za pristup dinamički alociranom nizu od “max_br_timova ” elemenata, pri čemu je svaki element niza pokazivač na objekat tipa “Tim ”. Interfejs klase treba da izgleda ovako: explicit Liga( int velicina_lige); ~Liga(); void DodajNoviTim( const char ime_tima[]); void RegistrirajUtakmicu( const char tim1[], const char tim2[], int rezultat_1, int rezultat_2); void IspisiTabelu();

Konstruktor treba da izvrši dinamičku alokaciju memorije za prihvatanje onoliko timova koliko je navedeno parametrom, dok destruktor treba da izvrši oslobađanje svih resursa koje je klasa “Liga ” alocirala tokom svog rada. Metoda “DodajNoviTim ” kreira tim sa navedenim imenom (tj. dinamički kreira objekat tipa “Tim ”) i upisuje ga na prvo slobodno mjesto u ligu (tj. upisuje pokazivač na njega na odgovarajuće mjesto u nizu pokazivača na objekte tipa “Tim ”). Pri tome se, naravno, broj timova u ligi povećava za jedinicu. Metoda ne smije da dozvoli upis više timova od maksimalno dozvoljenog broja timova. U metodi “RegistrirajUtakmicu ” prva dva parametra predstavljaju imena timova koji su odigrali utakmicu, dok su treći i četvrti parametar broj golova koji su dali prvi i drugi tim respektivno. Ova metoda treba da ažurira rezultate u tabeli za oba tima, odnosno da baci izuzetak ukoliko timovi sa navedenim imenima ne postoje u tabeli. Konačno, metoda “IspisiTabelu ” treba da ispiše tabelu lige sortiranu u opadajućem poretku po broju bodova. Ukoliko dva tima imaju isti broj poena, tada u tabeli prvo dolazi tim sa većom gol razlikom. Sortiranje vršite pozivom funkcije “sort ”, uz pogodno definiranu funkciju kriterija, koju trebate izvesti kao privatnu statičku funkciju članicu klase. Ispis treba vršiti pozivom metode “IspisiPodatke ” iz klase “Tim ”, tako da bi tabela trebala da ima izgled poput sljedećeg: Čelik 18 11 5 1 34 10 38 Jedinstvo 18 9 4 5 33 20 31 Željezni čar 18 9 4 5 25 19 31 Velež 18 8 6 4 23 24 30 Sarajevo 18 8 5 5 32 16 29

Kopiranje i međusobno dodjeljivanje primjeraka klase “Liga ” treba zabraniti. Obavezno treba napisati i testni program u kojem ćete demonstrirati sve elemente razvijenih klasa (“Tim ” i “Liga ”), na manjem broju fiksnih timova (npr. liga od 6 elemenata) i rezultatima utakmica koji se unose sa tastature. Predvidjeti i hvatanje eventualno bačenih izuzetaka. 3. Izmijenite klasu “Liga ” razvijenu u prethodnom zadatku, tako što će se za evidenciju pokazivača na dinamički alocirane objekte tipa “Tim ” umjesto dinamički alociranog niza pokazivača koristiti vektor čiji su elementi pokazivači na objekte tipa “Tim ”. Taj vektor će, naravno, biti privatni atribut klase (nazvaćemo ga isto “timovi ”, jer to traži najmanju prepravku klase). Privatni atributi “broj_timova ” i “ max_br_timova ” više neće biti potrebni. Zaista, broj timova se može saznati testiranjem trenutne veličine vektora, dok maksimalan broj timova više nije potrebno zadavati, s obzirom da vektor može u toku rada po volji povećavati svoju veličinu (ograničeni smo isključivo količinom raspoložive memorije). Jedina izmjena u interfejsu klase biće u tome što konstruktoru više neće biti potreban parametar (zahvaljujući fleksibilnosti vektora, u ligu će se moći dodati onoliko timova koliko želimo, bez potrebe da unaprijed specificiramo njihov maksimalan broj). Naravno, destruktor će i dalje biti potreban (da oslobodi

Page 53: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

sve dinamički alocirane timove nakon što objekat tipa “Liga ” prestane postojati). Što se tiče semantičkih aspekata (tj. šta metode klase “Liga ” treba da rade), jedina razlika je u tome što metoda “DodajNoviTim ” ne mora provjeravati da li je dostignut maksimalan broj timova, s obzirom da ograničenje na maksimalan broj timova više ne postoji (osim ograničenja uvjetovanih količinom raspoložive memorije). Svi ostali aspekti funkcioniranja klase “Liga ” ostaju neizmijenjeni. NAPOMENA: Mali broj studenata će stići uraditi sva tri zadatka za vrijeme koje je predviđeno za tutorijal. Međutim, svim studentima se toplo savjetuje da dovrše samostalno one zadatke koje nisu stigli uraditi za vrijeme tutorijala, s obzirom da je razumijevanje ovog tipa zadataka od vitalne važnosti za polaganje drugog parcijalnog ispita. Ovo vrijedi i za zadatke sa narednih tutorijala! Izrada tutorijala 10 T10-1 I 2 #include <iostream> #include <iomanip> #include <algorithm> using namespace std; class Tim { //Tim::Attributes char ime[20]; int broj_odigranih; int broj_pobjeda; int broj_nerijesenih; int broj_poraza; int broj_datih; int broj_primljenih; int broj_poena; public: //Tim::Constructors Tim(const char ime[]) : broj_odigranih(0), broj_pobjeda(0), broj_nerijesenih(0), broj_poraza(0), broj_datih(0), broj_primljenih(0), broj_poena(0) { if (strlen(ime) == 0) throw "Bacen izuzetak u konstruktoru Tim::Tim(const char ime[]): Tim mora imati ime!"; if (strlen(ime) > 20) throw "Bacen izuzetak u konstruktoru Tim::Tim(const char ime[]): Uneseno ime je predugo!";

Page 54: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

strcpy(Tim::ime, ime); } //Tim::Getters const char* DajImeTima() const { return ime; } int DajBrojPoena() const { return broj_poena; } int DajGolRazliku() const { return broj_datih - broj_primljenih; } //Tim::Methods void ObradiUtakmicu(int broj_datih, int broj_primljenih); void IspisiPodatke() const { cout << resetiosflags(ios::right) << setw(20) << setiosflags(ios::left) << ime << "; " << setw(4) << setiosflags(ios::right) << broj_odigranih << ":" << setw(4) << broj_pobjeda << ":" << setw(4) << broj_nerijesenih << ":" << setw(4) << broj_poraza << ";" << setw(4) << broj_datih << ":" << setw(4) << broj_primljenih << ";" << setw(4) << broj_poena << endl; } //Tim::Static Methods static bool Kriterij(const Tim* tim1, const Tim* tim2) { return tim1->DajBrojPoena() > tim2->DajBrojPoena(); } }; void Tim::ObradiUtakmicu(int broj_datih, int broj_primljenih) { if (broj_datih < 0) throw "Bacen izuzetak u funkciji void Tim::ObradiUtakmicu(int broj_datih, int broj_primljenih): Argument broj_datih mora biti nenegativan!"; if (broj_primljenih < 0) throw "Bacen izuzetak u funkciji void Tim::ObradiUtakmicu(int broj_datih, int broj_primljenih): Argument broj_primljenih mora biti nenegativan!";

Page 55: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

broj_odigranih++; if (broj_datih > broj_primljenih) { broj_pobjeda++; broj_poena += 3; } if (broj_datih < broj_primljenih) broj_poraza++; if (broj_datih == broj_primljenih) { broj_nerijesenih++; broj_poena++; } Tim::broj_datih += broj_datih; Tim::broj_primljenih += broj_primljenih; } class Liga { //Liga::Attributes int broj_timova; const int max_br_timova; Tim** timovi; public: //Liga::Constructors & Destructor explicit Liga(int velicina_lige) : broj_timova(0), max_br_timova(velicina_lige), timovi(0) { if (velicina_lige <= 0) throw "Bacen izuzetak u konstruktoru Liga::Liga(int velicina_lige): Argument velicina_lige mora biti pozitivan broj!"; timovi = 0; timovi = new Tim*[max_br_timova]; for(int i = 0; i < max_br_timova; i++) timovi[i] = 0; } Liga(const Liga&); Liga& operator=(const Liga&); ~Liga() { for(int i = 0; i < broj_timova; i++) delete timovi[i]; delete[] timovi; }; public: //Liga::Methods void DodajNoviTim(const char ime_tima[]); void RegistrirajUtakmicu(const char tim1[], const char tim2[], int rezultat_1, int rezultat_2); void IspisiTabelu(); };

Page 56: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

void Liga::DodajNoviTim(const char ime_tima[]) { //Provjera dupliranja tima for(int i = 0; i < broj_timova; i++) { if (strcmp(ime_tima, timovi[i]->DajImeTima()) == 0) throw "Bacen izuzetak u funkciji void Liga::DodajNoviTim(const char ime_tima[]): Imena ekipa moraju biti jedinstvena!"; } if (broj_timova == max_br_timova) "Bacen izuzetak u funkciji void Liga::DodajNoviTim(const char ime_tima[]): Dostignuta maksimalna velicina lige!"; timovi[broj_timova] = new Tim(ime_tima); broj_timova++; } void Liga::RegistrirajUtakmicu(const char tim1[], const char tim2[], int rezultat_1, int rezultat_2) { Tim* ptim1 = 0; Tim* ptim2 = 0; for(int i = 0; i < broj_timova; i++) { if (strcmp(tim1, timovi[i]->DajImeTima()) == 0) ptim1 = timovi[i]; if (strcmp(tim2, timovi[i]->DajImeTima()) == 0) ptim2 = timovi[i]; } if (ptim1 == 0) throw "Bacen izuzetak u funkciji void Liga::RegistrirajUtakmicu(const char tim1[], const char tim2[], int rezultat_1, int rezultat_2): Ne postoji tim1!"; if (ptim2 == 0) throw "Bacen izuzetak u funkciji void Liga::RegistrirajUtakmicu(const char tim1[], const char tim2[], int rezultat_1, int rezultat_2): Ne postoji tim2!"; if(ptim1 == ptim2) throw "Bacen izuzetak u funkciji void Liga::RegistrirajUtakmicu(const char tim1[], const char tim2[], int rezultat_1, int rezultat_2): Imena timova ne smiju biti jednaka!"; ptim1->ObradiUtakmicu(rezultat_1, rezultat_2); ptim2->ObradiUtakmicu(rezultat_2, rezultat_1); } void Liga::IspisiTabelu() { sort(timovi, timovi + broj_timova, Tim::Kriterij); cout << endl << "Rezultati lige: " << endl; for(int i = 0; i < broj_timova; i++) timovi[i]->IspisiPodatke();

Page 57: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

cout << endl; } int main() { try { Tim t("NK Hrkljus"); t.IspisiPodatke(); t.ObradiUtakmicu(10, 5); t.IspisiPodatke(); t.ObradiUtakmicu(5, 5); t.IspisiPodatke(); t.ObradiUtakmicu(5, 10); //Ukljuciti za demonstraciju izuzetaka //t.IspisiPodatke(); //t.ObradiUtakmicu(-1, 5); } catch(const char exceptionMessage[]) { cerr << endl << endl << exceptionMessage << endl << endl; } try { Liga l(10); l.DodajNoviTim("NK Fail"); l.DodajNoviTim("NK Epic Fail"); l.DodajNoviTim("NK Hrkljus"); l.IspisiTabelu(); l.RegistrirajUtakmicu("NK Hrkljus", "NK Fail", 10, 0); l.IspisiTabelu(); l.RegistrirajUtakmicu("NK Epic Fail", "NK Fail", 10, 0); l.RegistrirajUtakmicu("NK Epic Fail", "NK Hrkljus", 10, 0); l.IspisiTabelu(); } catch(const char exceptionMessage[]) { cerr << endl << endl << exceptionMessage << endl << endl; } return 0; } T10-3 #include <iostream> #include <iomanip> #include <algorithm> #include <vector>

Page 58: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

using namespace std; class Tim { //Tim::Attributes char ime[20]; int broj_odigranih; int broj_pobjeda; int broj_nerijesenih; int broj_poraza; int broj_datih; int broj_primljenih; int broj_poena; public: //Tim::Constructors Tim(const char ime[]) : broj_odigranih(0), broj_pobjeda(0), broj_nerijesenih(0), broj_poraza(0), broj_datih(0), broj_primljenih(0), broj_poena(0) { if (strlen(ime) == 0) throw "Bacen izuzetak u konstruktoru Tim::Tim(const char ime[]): Tim mora imati ime!"; if (strlen(ime) > 20) throw "Bacen izuzetak u konstruktoru Tim::Tim(const char ime[]): Uneseno ime je predugo!"; strcpy(Tim::ime, ime); } //Tim::Getters const char* DajImeTima() const { return ime; } int DajBrojPoena() const { return broj_poena; } int DajGolRazliku() const { return broj_datih - broj_primljenih; } //Tim::Methods

Page 59: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

void ObradiUtakmicu(int broj_datih, int broj_primljenih); void IspisiPodatke() const { cout << resetiosflags(ios::right) << setw(20) << setiosflags(ios::left) << ime << "; " << setw(4) << setiosflags(ios::right) << broj_odigranih << ":" << setw(4) << broj_pobjeda << ":" << setw(4) << broj_nerijesenih << ":" << setw(4) << broj_poraza << ";" << setw(4) << broj_datih << ":" << setw(4) << broj_primljenih << ";" << setw(4) << broj_poena << endl; } //Tim::Static Methods static bool Kriterij(const Tim* tim1, const Tim* tim2) { return tim1->DajBrojPoena() > tim2->DajBrojPoena(); } }; void Tim::ObradiUtakmicu(int broj_datih, int broj_primljenih) { if (broj_datih < 0) throw "Bacen izuzetak u funkciji void Tim::ObradiUtakmicu(int broj_datih, int broj_primljenih): Argument broj_datih mora biti nenegativan!"; if (broj_primljenih < 0) throw "Bacen izuzetak u funkciji void Tim::ObradiUtakmicu(int broj_datih, int broj_primljenih): Argument broj_primljenih mora biti nenegativan!"; broj_odigranih++; if (broj_datih > broj_primljenih) { broj_pobjeda++; broj_poena += 3; } if (broj_datih < broj_primljenih) broj_poraza++; if (broj_datih == broj_primljenih) { broj_nerijesenih++; broj_poena++; } Tim::broj_datih += broj_datih; Tim::broj_primljenih += broj_primljenih; } class Liga { //Liga::Attributes vector<Tim*>timovi; //za pristup dinamicki alociranom nizu od max_broj_timova pri cemu je svaki elemenat niza pokazivac na objekat tipa tim public: //Liga::Constructors & Destructor

Page 60: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

explicit Liga() :timovi(0){} Liga(const Liga&); Liga& operator=(const Liga&); ~Liga() { for(int i = 0; i <timovi.size(); i++) delete timovi[i]; }; //Liga::Methods void DodajNoviTim(const char ime_tima[]); void RegistrirajUtakmicu(const char tim1[], const char tim2[], int rezultat_1, int rezultat_2); void IspisiTabelu(); }; void Liga::DodajNoviTim(const char ime_tima[]) { //Provjera dupliranja tima for(int i = 0; i < timovi.size(); i++) { if (strcmp(ime_tima, timovi[i]->DajImeTima()) == 0) throw "Bacen izuzetak u funkciji void Liga::DodajNoviTim(const char ime_tima[]): Imena ekipa moraju biti jedinstvena!"; } timovi.resize(timovi.size()+1); timovi[timovi.size()-1] = new Tim(ime_tima); } void Liga::RegistrirajUtakmicu(const char tim1[], const char tim2[], int rezultat_1, int rezultat_2) { Tim* ptim1 = 0; Tim* ptim2 = 0; for(int i = 0; i < timovi.size(); i++) { if (strcmp(tim1, timovi[i]->DajImeTima()) == 0) ptim1 = timovi[i]; if (strcmp(tim2, timovi[i]->DajImeTima()) == 0) ptim2 = timovi[i]; } if (ptim1 == 0) throw "Bacen izuzetak u funkciji void Liga::RegistrirajUtakmicu(const char tim1[], const char tim2[], int rezultat_1, int rezultat_2): Ne postoji tim1!"; if (ptim2 == 0) throw "Bacen izuzetak u funkciji void Liga::RegistrirajUtakmicu(const char tim1[], const char tim2[], int rezultat_1, int rezultat_2): Ne postoji tim2!";

Page 61: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

if(ptim1 == ptim2) throw "Bacen izuzetak u funkciji void Liga::RegistrirajUtakmicu(const char tim1[], const char tim2[], int rezultat_1, int rezultat_2): Imena timova ne smiju biti jednaka!"; ptim1->ObradiUtakmicu(rezultat_1, rezultat_2); ptim2->ObradiUtakmicu(rezultat_2, rezultat_1); } void Liga::IspisiTabelu() { sort(timovi.begin(),timovi.end() , Tim::Kriterij); cout << endl << "Rezultati lige: " << endl; for(int i = 0; i < timovi.size(); i++) timovi[i]->IspisiPodatke(); cout << endl; } int main() { try { Tim t("Velez"); t.IspisiPodatke(); t.ObradiUtakmicu(10, 5); t.IspisiPodatke(); t.ObradiUtakmicu(5, 5); t.IspisiPodatke(); t.ObradiUtakmicu(5, 10); //Ukljuciti za demonstraciju izuzetaka //t.IspisiPodatke(); //t.ObradiUtakmicu(-1, 5); } catch(const char exceptionMessage[]) { cerr << endl << endl << exceptionMessage << endl << endl; } try { Liga l; l.DodajNoviTim("Sarajevo"); l.DodajNoviTim("Zeljeznicar"); l.DodajNoviTim("Olimpic"); l.DodajNoviTim("Velez"); l.IspisiTabelu(); l.RegistrirajUtakmicu("Sarajevo", "Zeljeznicar", 10, 0); l.IspisiTabelu(); l.RegistrirajUtakmicu("Velez", "Sarajevo", 3, 2); l.RegistrirajUtakmicu("Sarajevo", "Velez", 1, 0);

Page 62: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

l.IspisiTabelu(); } catch(const char exceptionMessage[]) { cerr << endl << endl << exceptionMessage << endl << endl; } return 0; }

Zadaci za Tutorial 11. 1. Izmijenite klasu “Vektor3d ” razvijenu u Zadatku 1. sa Tutoriala 8. tako da se umjesto metoda “SaberiSa ” i “ PomnoziSaSkalarom ” koriste operatori “+=” i “ *= ”, umjesto prijateljske funkcije “ZbirVektora ” operator “+” i umjesto metode “Ispisi ” operator “<<” (tako da umjesto “v1.SaberiSa(v2) ”, “ v3 = ZbirVektora(v1, v2) ” i “ v1.Ispisi() ” možemo prosto pisati “v1 += v2 ”, “ v3 = v1 + v2 ” i “ cout << v1 ”. Pri tome se podrazumijeva da ćete odgovarajuće izmjene izvršiti i u testnom programu koji demonstrira rad klase. Radi jednostavnijeg rada, klasi dodajte i konstruktor bez parametara, koji inicijalizira sve koordinate vektora na nule, kao i konstruktor sa tri parametra, koji inicijalizira koordinate vektora na vrijednosti zadane parametrima. 2. Izmijenite klasu “Sat ” razvijenu u Zadatku 3. sa Tutoriala 8. tako da se umjesto metoda “Sljedeci ” i “ Prethodni ” koriste operatori “++” i “ ––” (pri čemu je potrebno podržati kako prefiksne, tako i postfiksne verzije ovih operatora), umjesto metode “PomjeriZa ” operator “+=”, a umjesto metode “Ispisi ” operator “<<”. Testni program prilagodite novom interfejsu klase. Radi jednostavnijeg rada, dodajte ovoj klasi i pogodne konstruktore. 3. Neka je dat pobrojani tip enum Dani {Ponedjeljak, Utorak, Srijeda, Cetvrtak, Petak , Subota, Nedjelja};

Poznato je da se, u odsustvu drugačijih uputa, promjenljive tipa “Dani ” automatski konvertiraju u cjelobrojne vrijednosti. Na primjer, ukoliko promjenljiva “d” tipa “Dani ” ima vrijednosti “Srijeda ”, naredba poput “cout << d ” će umjesto teksta “Srijeda” ispisati broj 2. Srećom, ovakvo ponašanje se može izmijeniti korištenjem preklapanja operatora. Napišite operatorsku funkciju za operator “<<” koji će omogućiti da se prilikom ispisa konstanti, promjenljivih i izraza tipa “Dani ” umjesto brojčane vrijednosti dobijene konverzijom ispisuje tekst koji odgovara njihovom značenju. Testirajte napisanu funkciju u testnom programu koji sadrži petlju for (Dani d = Ponedjeljak; d <= Nedjelja; d++) cout << d << endl; Takva petlja treba da zaista ispiše imena dana u sedmici, a ne brojeve od 0 do 6. 4. Mada je već odavno u čitavom svijetu izvršena standardizacija mjernih jedinica za razne fizikalne veličine (SI sistem), Sjedinjene Američke Države se uporno opiru uvođenju ovih jedinica, nego u internoj upotrebi i dalje koriste svoje vlastite mjerne jedinice, koje su, uz neke izmjene, uglavnom naslijeđene iz Britanskog kraljevstva (interesantno je da su još jedine dvije države na svijetu pored SAD-a koje se opiru uvođenju SI sistema Liberija i Mjanmar, bivša Burma). Tako se, u SAD-u, dužine uglavnom izražavaju u inčima (inch), stopama (feet), jardima (yard) i miljama (mile). Tako, jedna stopa ima 12 inča, jedan jard ima 3 stope, dok jedna milja ima 1760 jardi (niđe veze, što bi rekli u Hercegovini). Veza sa SI sistemom lako se izvodi znajući da jedan inč iznosi 2,54 centimetra. Napravite klasu koja omogućava računanje sa američkim mjerama za dužinu, kao i pretvorbe između američkog i standardnog sistema mjerenja dužine. Interfejs klase treba da sadrži sljedeće elemente: • Konstruktor sa tri cjelobrojna parametra koja omogućava zadavanje dužine u jardima, stopama i inčima (milje ćemo ovdje zanemariti), npr. 9 jardi, 2 stope i 7 inča. Vrijednosti ovih parametara ne moraju biti ograničene (npr. broj inča ne mora biti u opsegu od 0 do 11). Stoga je, recimo, sasvim legalno zadati 5 jardi, 7 stopa i 14 inča, ali treba imati na umu da je

Page 63: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

to isto što i 7 jardi, 2 stope i 2 inča. Kako su parametri cjelobrojni, smatraćemo da nas ne zanimaju dijelovi inča, odnosno sve dužine uvijek će imati cijeli broj inča. • Konstruktor sa jednim realnim parametrom, koji omogućava da se dužina zada u metrima. Unutar ovog konstruktora potrebno je izvršiti pretvorbu metričkih u američke mjerne jedinice. Rezultat pretvorbe treba zaokružiti na cijeli broj inča. 2 • Metodu sa tri cjelobrojna parametra koja očitava broj jardi, stopa i inča pohranjen u objektu i smješta ih respektivno u tri navedena parametra. Pri tome, očitane vrijednosti moraju biti normalizirane u smislu da broj inča uvijek mora biti u opsegu od 0 – 11 a broj stopa u opsegu 0 – 2. • Metodu koja kao rezultat daje pohranjenu dužinu u metrima (kao realan broj). • Preklopljeni operator “+” koji daje kao rezultat novu dužinu koja je jednaka zbiru dužina koje su zadane kao operandi. • Preklopljeni operator “+=” koji obezbjeđuje da izraz oblika “X += Y ” uvijek ima isto značenje kao i izraz “X = X + Y ”. • Preklopljeni operator “++” koji povećava dužinu pohranjenu u objektu za 1 inč. Potrebno je podržati i prefiksnu i postfiksnu verziju ovog operatora. • Preklopljeni operator “* ” koji omogućava množenje dužine sa realnim brojem odnosno množenje realnog broja sa dužinom (množenje dvije dužine ne treba podržati, jer rezultat takvog množenja nije dužina, nego površina), dajući novu dužinu kao rezultat. Rezultat se zaokružuje na cijeli broj inča. • Preklopljeni operator “/ ” koji dijeli dvije dužine i daje realni broj kao rezultat (jednak odnosu dužina koje se dijele). • Preklopljeni operator “<<” koji omogućava ispis dužina na izlazni tok u formatu “a yd b ft c in ” (recimo “9 yd 2 ft 7 in ”). Obavezno napišite i kratki testni program u kojem ćete testirati napisanu klasu. U ovom zadatku namjerno nije rečeno šta su atributi klase koju treba razviti. U načelu, za atribute možete uzeti šta god hoćete što Vam treba da ova klasa radi ono što treba da radi (to i jeste poenta enkapsulacije i skrivanja informacija). Međutim, sama implementacija klase će bitno ovisiti od toga šta uzmete da su atributi. U zavisnosti od izbora, implementacija može biti izuzetno jednostavna, ali i prilično komplicirana. Zato nemojte biti brzopleti i dobro razmislite šta uzeti za atribute. Rješenje koje prvo pada na pamet nije nužno i najpametnije rješenje. Stoga, ukoliko Vam se rješavanje ovog zadatka primijetno zakomplicira, znajte da je do Vas. NAPOMENA: Mnogi studenti neće uspjeti uraditi sva četiri zadatka za vrijeme koje je predviđeno za tutorijal. Međutim, svim studentima se toplo savjetuje da dovrše samostalno one zadatke koje nisu stigli uraditi za vrijeme tutorijala, s obzirom da je razumijevanje ovog tipa zadataka od vitalne važnosti za polaganje drugog parcijalnog ispita. Ovo vrijedi i za zadatke sa narednih tutorijala! T11-1 #include <iostream> #include <cmath> using namespace std; class Vektor3d { double x,y,z; public: Vektor3d(): x(0), y(0), z(0) {}

Page 64: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

Vektor3d (double x, double y, double z) : x(x), y(y), z(z) {} void Postavi (double x, double y, double z) { Vektor3d::x=x; Vektor3d::y=y; Vektor3d::z=z; } void Postavix (double x) { Vektor3d::x=x; } void Postaviy (double y) { Vektor3d::y=y; } void Postaviz (double z) { Vektor3d::z=z; } void Ocitaj (double &x, double &y, double &z) const { x=Vektor3d::x; y=Vektor3d::y; z=Vektor3d::z; } double Dajx() const { return x; } double Dajy() const { return y; } double Dajz() const { return z; } double DajDuzinu() const { return sqrt(x*x + y*y + z*z); } void operator +=(const Vektor3d &v1){ x+=v1.Dajx(); y+=v1.Dajy(); z+=v1.Dajz(); } void operator *= (double s) { x*=s; y*=s; z*=s; } friend ostream &operator <<(ostream &izlaz, const Vektor3d &v1) { return izlaz<<"{"<<v1.Dajx()<<","<<v1.Dajy()<<","<<v1.Dajz()<<"}"; } }; Vektor3d operator +(const Vektor3d &v1, const Vektor3d &v2){ return Vektor3d(v1.Dajx() + v2.Dajx(), v1.Dajy() + v2.Dajy(), v1.Dajz() + v2.Dajz()); } int main() { double a(0),b(0),c(0); Vektor3d prvi, drugi, treci; cout << "Unesi koordinatu x: " << endl; cin>>a; cout << "Unesi koordinatu y: " << endl; cin>>b; cout << "Unesi koordinatu z: " << endl; cin>>c;

Page 65: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

prvi.Postavi(a,b,c); cout << "Unesi koordinatu x: " << endl; cin>>a; cout << "Unesi koordinatu y: " << endl; cin>>b; cout << "Unesi koordinatu z: " << endl; cin>>c; drugi.Postavi(a,b,c); cout<<prvi<<endl<<drugi<<endl; treci=prvi+drugi; cout<<treci<<endl; prvi+=treci; cout<<prvi; return 0; } T11-2 #include <iostream> using namespace std; class Sat { int sati, minute, sekunde; public: Sat () : sati(0), minute(0), sekunde(0) {} Sat (int s, int m, int sek) : sati(s), minute(m), sekunde(sek){} void Postavi (int h, int m, int s); friend Sat &operator ++(Sat &s); friend Sat operator ++(Sat &s, int); friend Sat &operator --(Sat &s); friend Sat operator --(Sat &s, int); void Prethodni(); void operator+= (int pomak); int DajSate () const { return sati; } int Dajminutee () const { return minute; } int DajSekunde () const { return sekunde; } friend ostream &operator <<(ostream &cout, Sat &s); }; int main() { try{ int a,b,c,broj; Sat digitalni;

Page 66: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

cout << "Unesi broj sati: "<<endl; cin>>a; cout << "Unesi broj minuta: "<<endl; cin>>b; cout << "Unesi broj sekundi: "<<endl; cin>>c; digitalni.Postavi(a,b,c); cout<<"Uneseno vrijeme je: "; cout<<digitalni; ++digitalni; cout<<"\nVrijeme pomjereno za 1 sekundu od unesenog vremena je: "; cout<<digitalni<<endl; cout<<"Unesi broj sekundi za koje zelite pomjeriti vrijeme: "; cin>>broj; digitalni+=broj; cout<<endl<<digitalni<<endl; cout<<"Vrijeme pomjereno 1 sekundu unazad ima: "; digitalni--; cout<<digitalni.DajSate()<<" sati, "<<digitalni.Dajminutee()<<" minuta i "<<digitalni.DajSekunde()<<"sekundi."; } catch(const char poruka[]){ cout<<poruka<<endl; } return 0; } void Sat::Postavi(int h, int m, int s){ { if(h<0 || h>24 || m<0 || m>60 || s<0 || s>60) throw "Pogresni parametri"; Sat::sati=h; Sat::minute=m; Sat::sekunde=s; }} ostream &operator<<(ostream &cout, Sat &s) { if(s.sati==0) { cout<<"(00,"; } else cout<<"("<<s.sati; if(s.minute==0) { cout<<"00,"; } else cout<<","<<s.minute<<","; if(s.sekunde==0) { cout<<"00)"; } else cout<<s.sekunde<<")";

Page 67: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

return cout; } Sat &operator ++(Sat &s) { s.sekunde++; if(s.sekunde==60) { s.minute++; s.sekunde=0; } if(s.minute==60) { s.sati++; s.minute=0; } if(s.sati==24) s.sati=0; return s; } Sat operator ++(Sat &s, int){ Sat pomocni(s.sati, s.minute, s.sekunde); ++s; return pomocni; } Sat &operator--(Sat &s){ s.sekunde--; if(s.sekunde==-1) { s.sekunde=59; s.minute--; { if(s.minute==-1) s.minute=59; s.sati--; { if(s.sati==-1) s.sati=23; }}} return s; } Sat operator--(Sat &s,int){ Sat pomocni(s.sati, s.minute, s.sekunde); --s; return pomocni; } void Sat::operator+= (int pomak){ sekunde+=pomak; if(sekunde>60){ while(sekunde>60){ sekunde-=60; minute++; }} if(sekunde==60) { sekunde=0; minute++; } if(minute>60){ while(minute>60){

Page 68: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

minute-=60; sati++; }} if(minute==60) { minute=0; sati++; } if(sati>24){ while(sati>24){ sati-=24; } } if(sati==24) sati=0; } T11-3 #include <iostream> #include <string> using namespace std; enum Dani {Ponedjeljak, Utorak, Srijeda, Cetvrtak, Petak, Subota, Nedjelja}; Dani &operator++ (Dani &d){ return d=Dani((int(d)+1)%7); } Dani operator ++ (Dani &d,int){ Dani pomocni(d); ++d; return pomocni; } ostream &operator<<(ostream &cout, const Dani &d){ string nazivi[]={"Ponedjeljak","Utorak","Srijeda","Cetvrtak","Petak","Subota","Nedjelja"}; return cout<<nazivi[static_cast<int>(d)]; } int main() { for(Dani d = Ponedjeljak; d <= Nedjelja; d++) { cout << d << endl; if(d==Nedjelja) break; } return 0; }

II PARCIJALNI ISPIT IZ PREDMETA “TEHNIKE PROGRAMIRANJA” NAPOMENA: Sve funkcije čija je implementacija duža od dvije naredbe obavezno implementirajte izvan klase. Također, sve metode koje su inspektori obavezno deklarirajte kao takve.

Page 69: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

Zadatak 1a (7,5 poena): U kompjuterskoj grafici veoma se često javlja potreba za radom sa matricama, pri čemu te matrice nikada nemaju format veći od 4 × 4 (mogući su i manji formati). Stoga je, radi lakšeg rada sa ovakvim matricama, veoma praktično razviti posebnu klasu, koju možemo nazvati recimo “GMatrica ”. Vaš zadatak je da razvijete upravo takvu klasu, u skladu sa opisom koji slijedi. S obzirom da su maksimalne dimenzije takvih matrica ograničene na 4 × 4, nema potrebe za korištenjem dinamičke alokacije memorije, niti fleksibilnih tipova podataka kao što su vektori (odnosno vektori vektôrā). Stoga elemente matrice čuvajte u atributu koji je obični dvodimenzionalni niz realnih brojeva formata 4 × 4. Međutim, kako format matrice može biti i manji od 4 × 4, predvidite i dva atributa koji čuvaju stvarni broj redova i kolona matrice (naravno, u slučaju kada je format manji od 4 × 4, neki elementi dvodimenzionalnog niza pohranjenog unutar odgovarajućeg atributa biće neiskorišteni). Pored navedenih atributa, klasa “GMatrica ” treba da sadrži i sljedeće: • Konstruktor sa tri parametra, koji redom predstavljaju broj redova, broj kolona i vrijednost na koju se inicijaliziraju svi elementi matrice. Ovaj posljednji parametar ima podrazumijevanu vrijednost 0 koja se koristi ukoliko se on izostavi. U slučaju da broj redova ili broj kolona nisu legalni (u skladu sa postavkom zadatka), treba baciti izuzetak. • Konstruktor sa jednim parametrom koji je dvodimenzionalni niz realnih brojeva formata 4 × 4. Ovaj konstruktor prosto kreira objekat tipa “GMatrica ” koji modelira matricu formata 4 × 4 i inicijalizira je odgovarajućim vrijednostima iz dvodimenzionalnog niza koji je zadan kao parametar. Glavna uloga ovog konstruktora je da omogući automatsku konverziju dvodimenzionalnih nizova realnih brojeva formata 4 × 4 u objekte tipa “GMatrica ”. • Metode koje daju broj redova odnosno broj kolona matrice. • Preklopljeni operator “+” koji daje kao rezultat zbir matrica predstavljenih operandima. Matrice se mogu sabirati samo ukoliko su istog formata, u suprotnom treba baciti izuzetak. Pri tome, odgovarajuća operatorska funkcija ne treba da bude funkcija članica. Napomena: da uštedite na pisanju, uputno je ovaj operator implementirati preko operatora “+=”. • Preklopljeni operator “* ” koji daje kao rezultat proizvod matrica predstavljenih operandima, odnosno proizvod matrice sa realnim brojem, pri čemu je matrica prvi operand a realni broj drugi, ili obrnuto. Matrice se mogu množiti samo ukoliko je broj kolona prve matrice jednak broju redova druge matrice. U suprotnom, treba baciti izuzetak. Odgovarajuće operatorske funkcije ne trebaju biti funkcije članice. Napomena: za one koji ne znaju, element u i-tom redu i j-toj koloni matrice koja je proizvod matrica A i B dobija se kao zbir proizvoda svih elemenata i-tog reda matrice A sa odgovarajućim elementima j-te kolone matrice B. • Preklopljeni operator “+=” koji obezbjeđuje da izraz oblika “X += Y ” uvijek ima isto značenje kao i izraz “X = X + Y ”. Odgovarajuća operatorska funkcija treba da bude funkcija članica. • Preklopljene operatore “==” i “ != ” koji testiraju da li su dvije matrice jednake odnosno različite. • Preklopljeni operator “() ” koji omogućava pristup elementu u i-tom redu i j-toj koloni matrice navođenjem i i j razdvojenih zarezom unutar zagrada (npr. “a(2, 3) ” predstavlja element matrice “a” u drugom redu i trećoj koloni). Indeksi redova i kolona treba da počinju od jedinice, kako je to uobičajeno u matematici notaciji. Ukoliko indeksi nisu legalni, treba baciti izuzetak. Operator treba da vrati referencu na odgovarajući element da bi se omogućilo korištenje ove notacije sa lijeve strane znaka jednakosti, osim u slučaju da se ovaj operator primijeni na konstantnu matricu (u tom slučaju, ne treba vraćati referencu na element, nego njegovu kopiju). • Preklopljeni operator “<<” koji omogućava ispis matrice na izlazni tok. Elementi matrice se ispisuju red po red, pri čemu se za ispis svakog elementa rezervira prostor od 8 znakova. • Metode koje snimaju sadržaj matrice u binarnu datoteku čije se ime navodi kao parametar, odnosno obnavljaju sadržaj matrice iz datoteke čije se ime navodi kao parametar. Zadatak 1b (1,5 poen): Opišite šta bi se tačno izmijenilo u realizaciji prethodnog zadatka ukoliko bi se tražilo da klasa “GMatrica ” bude generička, tako da se tip elemenata matrice može zadavati (npr. da se podrže

Page 70: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

matrice sa cjelobrojnim ili kompleksnim elementima). Posebno istaknite kako bi se izveo preklopljeni operator “+” i operatori slični njemu. Zadatak 2a (9,5 poena): Za vođenje evidencije podataka o robi u nekom skladištu potrebno je razviti kontejnersku klasu nazvanu “Skladiste ”. U skladištu se roba nalazi pohranjena u sanducima (za čvrste predmete) i u buradima (za tečnosti). Sanduci i burad se modeliraju redom pomoću klasa “Sanduk ” odnosno “Bure ”. Sanduk je opisan svojom težinom, nazivom predmeta koji se u njemu čuvaju (pretpostavlja se da jedan sanduk čuva samo istovrsne predmete), brojem predmeta koji se u njemu čuvaju i težinom predmeta koji se u njemu čuvaju (svi su iste težine). Bure je opisano svojom težinom, nazivom tečnosti koja se u njemu čuva, te težinom tečnosti koja se u njemu čuva. Informacijama o robi pohranjenoj u skladištu pristupa se pomoću dinamički alociranog niza pokazivača koji pokazuju na objekte tipa “Sanduk ” ili tipa “ Bure ” (za tu svrhu, obje klase “Sanduk ” i “ Bure ” će morati biti naslijeđene iz neke zajedničke apstraktne bazne klase). Tom nizu pokazivača se pristupa preko nekog od atributa pohranjenog unutar klase “Skladiste ”. Interfejs klasa “Sanduk ” i “ Bure ” omogućava da se saznaju težine sanduka odnosno bureta, sa i bez onoga što je u njima, kao i da se ispišu podaci o sanduku odnosno buretu i onome što je u njima (format ispisa odaberite po volji). Interfejs klase “Skladiste ” treba sadržavati sljedeće elemente: • Konstruktor sa jednim parametrom koji predstavlja maksimalnu količinu objekata (sanduka odnosno buradi) koji se mogu pohraniti u skladištu. Ovaj konstruktor se ne smije koristiti za automatsku pretvorbu cijelih brojeva u objekte tipa “Skladiste ”. • Destruktor, koji oslobađa svu memoriju koji su objekti tipa “Skladiste ” zauzeli tokom svog života. • Konstruktor kopije i preklopljeni operator dodjele koji omogućavaju bezbjedno kopiranje i međusobno dodjeljivanje objekata tipa “Skladiste ” zasnovano na strategiji dubokog kopiranja (nemojte zaboraviti da se radi o polimorfnoj kolekciji objekata). • Metode koje kreiraju novi objekat tipa “Sanduk ” odnosno “Bure ” i pohranjuju ga u skladište. Parametri ovih metoda trebaju biti u skladu sa informacijama koje su potrebne da se opiše sanduk odnosno bure. Ukoliko je skladište već popunjeno, treba baciti izuzetak. • Metode koje vraćaju reference na najlakši odnosno najteži objekat (bure ili sanduk) u skladištu, ne računajući ono što je pohranjeno u tom objektu. • Metodu koja vraća broj objekata u skladištu čija je ukupna težina (tj. vlastita težina zajedno sa težinom onoga što se u njima nalazi) veća od iznosa koji se zadaje kao parametar. • Metode koje ispisuju spisak svega što se nalazi u skladištu, sortiran u opadajući poredak po ukupnoj težini. Napisane klase demonstrirajte u testnom programu koji čita podatke o robi iz tekstualne datoteke, smješta robu u skladište i na kraju ispisuje sortirani spisak svega što se nalazi u skladištu. Svaki objekat opisan je sa dva reda u datoteci. U prvom redu se nalazi početno slovo “S” ili “ B” (za sanduk odnosno za bure) iza kojeg nakon jednog razmaka slijedi naziv predmeta ili tečnosti koje su pohranjene u sanduku odnosno buretu (npr. “S Tepsije ” ili “ B Suncokretovo ulje ”). U drugom redu se za slučaj sanduka nalazi težina sanduka, broj predmeta i težina svakog od njih, razdvojeno po jednim razmakom (npr. “1.2 50 0.35 ”) dok se za slučaj bureta nalazi težina bureta i težina tečnosti (npr. “0.8 16.5 ”). Radi jednostavnosti, pretpostavite da datoteka sadrži isključivo ispravne podatke. NAPOMENA: U privatne dijelove klasa imate pravo stavljati šta god Vam treba da bi tražene klase funkcionirale u skladu sa postavkom zadatka. Zadatak 2b (1,5 poen): Opišite šta bi se tačno izmijenilo u realizaciji prethodnog zadatka ukoliko bi se za pristup informacijama

Page 71: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

o robi pohranjenoj u skladištu umjesto dinamički alociranog niza pokazivača koji pokazuju na objekte tipa “Sanduk ” ili tipa “ Bure ” koristio vektor pokazivača koje pokazuju na iste takve objekte.

I-a #include <iostream> #include <algorithm> #include <iomanip> #include <fstream> using namespace std; class GMatrica { double podaci[4][4]; int redova, kolona; public: GMatrica(int redova, int kolona, double vrijednost = 0); GMatrica(double vrijednost) :redova(4), kolona(4) { fill(&(podaci[0][0]), &(podaci[3][3])+1, vrijednost); } int DajRedova() const { return redova; } int DajKolona() const { return kolona; } friend GMatrica operator+(const GMatrica &m1, const GMatrica &m2); friend GMatrica operator*(const GMatrica &m1, const GMatrica &m2); friend GMatrica operator*(const GMatrica &m, double k); friend GMatrica operator*(double k, const GMatrica &m) { return m*k; } GMatrica &operator+=(const GMatrica &m); bool operator==(const GMatrica &m) const; bool operator!=(const GMatrica &m) const { return !((*this)==m); } double &operator()(int i, int j); double operator()(int i, int j) const { return (*this)(i, j); } friend ostream& operator<<(ostream &out, const GMatrica& m); void Snimi(const char *ime_datoteke) const; void Obnovi(const char *ime_datoteke); }; GMatrica::GMatrica(int redova, int kolona, double vrijednost) :redova(redova), kolona(kolona) { fill(&(podaci[0][0]), &(podaci[3][3])+1, vrijednost); // for (int i = 0; i < redova; ++i)

Page 72: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

// for (int j = 0; j < kolona; ++j) // podaci[i][j] = vrijednost; } GMatrica operator+(const GMatrica &m1, const GMatrica &m2) { GMatrica m3(m1); m3 += m2; return m3; } GMatrica operator*(const GMatrica &m1, const GMatrica &m2) { if (m1.DajKolona() != m2.DajRedova()) throw "Matrice nisu saglasne za mnozenje."; GMatrica m3(m1.DajRedova(), m2.DajKolona()); for (int i = 0; i < m1.DajRedova(); ++i) for (int j = 0; j < m2.DajKolona(); ++j) { m3.podaci[i][j] = 0; for (int k = 0; k < m1.DajKolona(); ++k) m3.podaci[i][j] += m1.podaci[i][k]*m2.podaci[k][j]; } return m3; } GMatrica operator*(const GMatrica &m, double k) { GMatrica m1(m); for (int i = 0; i < m1.DajRedova(); ++i) for (int j = 0; j < m1.DajKolona(); ++j) m1.podaci[i][j] *= k; return m1; } GMatrica &GMatrica::operator+=(const GMatrica &m) { if (DajKolona() != m.DajKolona() || DajRedova() != m.DajRedova()) throw "Matrice nisu saglasne za sabiranje."; for (int i = 0; i < DajRedova(); ++i) for (int j = 0; j < DajKolona(); ++j) podaci[i][j] += m.podaci[i][j]; return *this; }

Page 73: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

bool GMatrica::operator==(const GMatrica &m) const { if (DajKolona() != m.DajKolona() || DajRedova() != m.DajRedova()) return false; for (int i = 0; i < DajRedova(); ++i) for (int j = 0; j < DajKolona(); ++j) if (podaci[i][j] != m.podaci[i][j]) return false; return true; } double &GMatrica::operator()(int i, int j) { if (i < 1 || i > redova || j < 1 || j > kolona) throw "Indeksi za pristup elementu matrice su izvan opsega."; return podaci[i-1][j-1]; } ostream& operator<<(ostream &out, const GMatrica& m) { for (int i = 0; i < m.DajRedova(); ++i) { for (int j = 0; j < m.DajKolona(); ++j) out << setw(8) << m.podaci[i][j]; out << "\n"; } return out; } void GMatrica::Snimi(const char *ime_datoteke) const { fstream fout(ime_datoteke, ios::out | ios::binary); fout.write((char*)&redova, sizeof redova); fout.write((char*)&kolona, sizeof kolona); for (int i = 0; i < DajRedova(); ++i) for (int j = 0; j < DajKolona(); ++j) fout.write((char*)&(podaci[i][j]), sizeof podaci[i][j]); } void GMatrica::Obnovi(const char *ime_datoteke) { ifstream fout(ime_datoteke, ios::binary); fout.read((char*)&redova, sizeof redova);

Page 74: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

fout.read((char*)&kolona, sizeof kolona); for (int i = 0; i < DajRedova(); ++i) for (int j = 0; j < DajKolona(); ++j) fout.read((char*)&(podaci[i][j]), sizeof podaci[i][j]); } int main() { GMatrica m1(1); m1.Snimi("matrica.dat"); cout << m1; return 0; }

I-b #include <iostream> #include <algorithm> #include <iomanip> #include <fstream> using namespace std; template <typename Tip> class GMatrica { Tip podaci[4][4]; int redova, kolona; public: GMatrica(int redova, int kolona, Tip vrijednost = 0); GMatrica(Tip vrijednost) :redova(4), kolona(4) { fill(&(podaci[0][0]), &(podaci[3][3])+1, vrijednost); } int DajRedova() const { return redova; } int DajKolona() const { return kolona; } template <typename Tip2> friend GMatrica<Tip2> operator+(const GMatrica<Tip2> &m1, const GMatrica<Tip2> &m2); template <typename Tip2> friend GMatrica<Tip2> operator*(const GMatrica<Tip2> &m1, const GMatrica<Tip2> &m2); template <typename Tip2> friend GMatrica<Tip2> operator*(const GMatrica<Tip2> &m, Tip2 k); template <typename Tip2>

Page 75: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

friend GMatrica<Tip2> operator*(Tip2 k, const GMatrica &m) { return m*k; } GMatrica &operator+=(const GMatrica<Tip> &m); bool operator==(const GMatrica<Tip> &m) const; bool operator!=(const GMatrica<Tip> &m) const { return !((*this)==m); } Tip &operator()(int i, int j); Tip operator()(int i, int j) const { return (*this)(i, j); } template <typename Tip2> friend ostream& operator<<(ostream &out, const GMatrica<Tip2>& m); void Snimi(const char *ime_datoteke) const; void Obnovi(const char *ime_datoteke); }; template <typename Tip> GMatrica<Tip>::GMatrica(int redova, int kolona, Tip vrijednost) :redova(redova), kolona(kolona) { fill(&(podaci[0][0]), &(podaci[3][3])+1, vrijednost); // for (int i = 0; i < redova; ++i) // for (int j = 0; j < kolona; ++j) // podaci[i][j] = vrijednost; } template <typename Tip> GMatrica<Tip> operator+(const GMatrica<Tip> &m1, const GMatrica<Tip> &m2) { GMatrica<Tip> m3(m1); m3 += m2; return m3; } template <typename Tip> GMatrica<Tip> operator*(const GMatrica<Tip> &m1, const GMatrica<Tip> &m2) { if (m1.DajKolona() != m2.DajRedova()) throw "Matrice nisu saglasne za mnozenje."; GMatrica<Tip> m3(m1.DajRedova(), m2.DajKolona()); for (int i = 0; i < m1.DajRedova(); ++i) for (int j = 0; j < m2.DajKolona(); ++j) { m3.podaci[i][j] = 0; for (int k = 0; k < m1.DajKolona(); ++k)

Page 76: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

m3.podaci[i][j] += m1.podaci[i][k]*m2.podaci[k][j]; } return m3; } template <typename Tip> GMatrica<Tip> operator*(const GMatrica<Tip> &m, Tip k) { GMatrica<Tip> m1(m); for (int i = 0; i < m1.DajRedova(); ++i) for (int j = 0; j < m1.DajKolona(); ++j) m1.podaci[i][j] *= k; return m1; } template <typename Tip> GMatrica<Tip> &GMatrica<Tip>::operator+=(const GMatrica<Tip> &m) { if (DajKolona() != m.DajKolona() || DajRedova() != m.DajRedova()) throw "Matrice nisu saglasne za sabiranje."; for (int i = 0; i < DajRedova(); ++i) for (int j = 0; j < DajKolona(); ++j) podaci[i][j] += m.podaci[i][j]; return *this; } template <typename Tip> bool GMatrica<Tip>::operator==(const GMatrica<Tip> &m) const { if (DajKolona() != m.DajKolona() || DajRedova() != m.DajRedova()) return false; for (int i = 0; i < DajRedova(); ++i) for (int j = 0; j < DajKolona(); ++j) if (podaci[i][j] != m.podaci[i][j]) return false; return true; } template <typename Tip> Tip &GMatrica<Tip>::operator()(int i, int j) { if (i < 1 || i > redova || j < 1 || j > kolona) throw "Indeksi za pristup elementu matrice su izvan opsega."; return podaci[i-1][j-1];

Page 77: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

} template <typename Tip> ostream& operator<<(ostream &out, const GMatrica<Tip>& m) { for (int i = 0; i < m.DajRedova(); ++i) { for (int j = 0; j < m.DajKolona(); ++j) out << setw(8) << m.podaci[i][j]; out << "\n"; } return out; } template <typename Tip> void GMatrica<Tip>::Snimi(const char *ime_datoteke) const { fstream fout(ime_datoteke, ios::out | ios::binary); fout.write((char*)&redova, sizeof redova); fout.write((char*)&kolona, sizeof kolona); for (int i = 0; i < DajRedova(); ++i) for (int j = 0; j < DajKolona(); ++j) fout.write((char*)&(podaci[i][j]), sizeof podaci[i][j]); } template <typename Tip> void GMatrica<Tip>::Obnovi(const char *ime_datoteke) { ifstream fout(ime_datoteke, ios::binary); fout.read((char*)&redova, sizeof redova); fout.read((char*)&kolona, sizeof kolona); for (int i = 0; i < DajRedova(); ++i) for (int j = 0; j < DajKolona(); ++j) fout.read((char*)&(podaci[i][j]), sizeof podaci[i][j]); } int main() { GMatrica<int> m1(1); m1.Obnovi("matrica.dat"); cout << m1; return 0; }

Page 78: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

II-a #include <iostream> #include <typeinfo> #include <string> #include <algorithm> #include <fstream> #include <iomanip> using namespace std; class Objekat { public: virtual double DajTezinuPrazan() const = 0; virtual double DajTezinuPun() const = 0; virtual void Ispisi() const = 0; }; class Sanduk : public Objekat { double tezina; string naziv_predmeta; double tezina_predmeta; int broj_predmeta; public: Sanduk(double tezina, string naziv_predmeta, double tezina_predmeta, int broj_predmeta) :tezina(tezina), naziv_predmeta(naziv_predmeta), tezina_predmeta(tezina_predmeta), broj_predmeta(broj_predmeta) {} virtual double DajTezinuPrazan() const { return tezina; } virtual double DajTezinuPun() const { return tezina + tezina_predmeta*broj_predmeta; } virtual void Ispisi() const { cout << "Sanduk ukupne tezine " << DajTezinuPun() << " sadrzi " << broj_predmeta << " " << naziv_predmeta << ".\n"; } }; class Bure : public Objekat { double tezina;

Page 79: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

string naziv_tecnosti; double tezina_tecnosti; public: Bure(double tezina, string naziv_tecnosti, double tezina_tecnosti) :tezina(tezina), naziv_tecnosti(naziv_tecnosti), tezina_tecnosti(tezina_tecnosti) {} virtual double DajTezinuPrazan() const { return tezina; } virtual double DajTezinuPun() const { return tezina + tezina_tecnosti; } virtual void Ispisi() const { cout << "Bure ukupne tezine " << DajTezinuPun() << " sadrzi " << naziv_tecnosti << ".\n"; } }; class Skladiste { Objekat **podaci; int maks_objekata, objekata; static bool Kriterij(const Objekat *o1, const Objekat *o2) { return o1->DajTezinuPun() > o2->DajTezinuPun(); } public: explicit Skladiste(int maks_objekata) :podaci(new Objekat*[maks_objekata]), maks_objekata(maks_objekata), objekata(0) {} ~Skladiste(); Skladiste(const Skladiste &s); Skladiste& operator=(const Skladiste &s); void DodajSanduk(double tezina, string naziv_predmeta, double tezina_predmeta, int broj_predmeta); void DodajBure(double tezina, string naziv_tecnosti, double tezina_tecnosti); Objekat& DajNajtezi(); Objekat& DajNajlaksi(); int BrojTezihOd(double tezina) const; void Ispisi(); }; Skladiste::~Skladiste() { for (int i = 0; i < objekata; ++i) delete podaci[i]; delete[] podaci; }

Page 80: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

Skladiste::Skladiste(const Skladiste &s) :podaci(new Objekat*[s.maks_objekata]), maks_objekata(s.maks_objekata), objekata(s.objekata) { for (int i = 0; i < objekata; ++i) if (typeid(*s.podaci[i]) == typeid(Sanduk)) podaci[i] = new Sanduk(*(Sanduk*)s.podaci[i]); else podaci[i] = new Bure(*(Bure*)s.podaci[i]); } Skladiste& Skladiste::operator=(const Skladiste &s) { for (int i = 0; i < objekata; ++i) delete podaci[i]; if (maks_objekata < s.maks_objekata) { delete[] podaci; podaci = new Objekat*[s.maks_objekata]; } maks_objekata = s.maks_objekata; objekata = s.objekata; for (int i = 0; i < objekata; ++i) if (typeid(*s.podaci[i]) == typeid(Sanduk)) podaci[i] = new Sanduk(*(Sanduk*)s.podaci[i]); else podaci[i] = new Bure(*(Bure*)s.podaci[i]); } void Skladiste::DodajSanduk(double tezina, string naziv_predmeta, double tezina_predmeta, int broj_predmeta) { if (objekata == maks_objekata) throw "Skladiste je popunjeno."; podaci[objekata++] = new Sanduk(tezina, naziv_predmeta, tezina_predmeta, broj_predmeta); } void Skladiste::DodajBure(double tezina, string naziv_tecnosti, double tezina_tecnosti) { if (objekata == maks_objekata) throw "Skladiste je popunjeno."; podaci[objekata++] = new Bure(tezina, naziv_tecnosti, tezina_tecnosti); }

Page 81: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

Objekat& Skladiste::DajNajtezi() { if (objekata == 0) throw "Skladiste je prazno."; int indeks_najtezeg = 0; for (int i = 1; i < objekata; ++i) if (podaci[i]->DajTezinuPrazan() > podaci[indeks_najtezeg]->DajTezinuPrazan()) indeks_najtezeg = i; return *podaci[indeks_najtezeg]; } Objekat& Skladiste::DajNajlaksi() { if (objekata == 0) throw "Skladiste je prazno."; int indeks_najlakseg = 0; for (int i = 1; i < objekata; ++i) if (podaci[i]->DajTezinuPrazan() < podaci[indeks_najlakseg]->DajTezinuPrazan()) indeks_najlakseg = i; return *podaci[indeks_najlakseg]; } int Skladiste::BrojTezihOd(double tezina) const { int broj_tezih_od = 0; for (int i = 0; i < objekata; ++i) if (podaci[i]->DajTezinuPun() > tezina) ++broj_tezih_od; return broj_tezih_od; } void Skladiste::Ispisi() { sort(podaci, podaci+objekata, Kriterij); cout << "Skladiste sadrzi sljedecih " << objekata << " objekata:\n"; for (int i = 0; i < objekata; ++i) podaci[i]->Ispisi(); } int main() { Skladiste s(10); ifstream fin("roba.txt");

Page 82: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

while (true) { char c; fin >> c >> ws; if (fin.eof()) break; string naziv; getline(fin, naziv); if (c == 'S') { double tezina, tezina_predmeta; int broj_predmeta; fin >> tezina >> broj_predmeta >> tezina_predmeta; s.DodajSanduk(tezina, naziv, tezina_predmeta, broj_predmeta); } else { double tezina, tezina_tecnosti; fin >> tezina >> tezina_tecnosti; s.DodajBure(tezina, naziv, tezina_tecnosti); } fin.ignore(10009, '\n'); } s.Ispisi(); Skladiste s2(1); s2 = s; s2.Ispisi(); Skladiste s3(15); s3 = s; s3.Ispisi(); Skladiste s4(s); s4.Ispisi(); cout << "Najlaksi: "; s4.DajNajlaksi().Ispisi(); cout << "Najtezi: "; s4.DajNajtezi().Ispisi(); cout << "Broj tezih od 20 je: " << s4.BrojTezihOd(20) << endl; return 0; }

Page 83: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

II-b #include <iostream> #include <typeinfo> #include <string> #include <algorithm> #include <fstream> #include <iomanip> #include <vector> using namespace std; class Objekat { public: virtual double DajTezinuPrazan() const = 0; virtual double DajTezinuPun() const = 0; virtual void Ispisi() const = 0; }; class Sanduk : public Objekat { double tezina; string naziv_predmeta; double tezina_predmeta; int broj_predmeta; public: Sanduk(double tezina, string naziv_predmeta, double tezina_predmeta, int broj_predmeta) :tezina(tezina), naziv_predmeta(naziv_predmeta), tezina_predmeta(tezina_predmeta), broj_predmeta(broj_predmeta) {} virtual double DajTezinuPrazan() const { return tezina; } virtual double DajTezinuPun() const { return tezina + tezina_predmeta*broj_predmeta; } virtual void Ispisi() const { cout << "Sanduk ukupne tezine " << DajTezinuPun() << " sadrzi " << broj_predmeta << " " << naziv_predmeta << ".\n"; } }; class Bure : public Objekat { double tezina; string naziv_tecnosti; double tezina_tecnosti;

Page 84: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

public: Bure(double tezina, string naziv_tecnosti, double tezina_tecnosti) :tezina(tezina), naziv_tecnosti(naziv_tecnosti), tezina_tecnosti(tezina_tecnosti) {} virtual double DajTezinuPrazan() const { return tezina; } virtual double DajTezinuPun() const { return tezina + tezina_tecnosti; } virtual void Ispisi() const { cout << "Bure ukupne tezine " << DajTezinuPun() << " sadrzi " << naziv_tecnosti << ".\n"; } }; class Skladiste { vector<Objekat*> podaci; int maks_objekata; static bool Kriterij(const Objekat *o1, const Objekat *o2) { return o1->DajTezinuPun() > o2->DajTezinuPun(); } public: explicit Skladiste(int maks_objekata) :maks_objekata(maks_objekata) {podaci.reserve(maks_objekata);} ~Skladiste(); Skladiste(const Skladiste &s); Skladiste& operator=(const Skladiste &s); void DodajSanduk(double tezina, string naziv_predmeta, double tezina_predmeta, int broj_predmeta); void DodajBure(double tezina, string naziv_tecnosti, double tezina_tecnosti); Objekat& DajNajtezi(); Objekat& DajNajlaksi(); int BrojTezihOd(double tezina) const; void Ispisi(); }; Skladiste::~Skladiste() { for (int i = 0; i < podaci.size(); ++i) delete podaci[i]; } Skladiste::Skladiste(const Skladiste &s) :maks_objekata(s.maks_objekata) {

Page 85: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

podaci.reserve(maks_objekata); for (int i = 0; i < s.podaci.size(); ++i) if (typeid(*s.podaci[i]) == typeid(Sanduk)) podaci.push_back(new Sanduk(*(Sanduk*)s.podaci[i])); else podaci.push_back(new Bure(*(Bure*)s.podaci[i])); } Skladiste& Skladiste::operator=(const Skladiste &s) { for (int i = 0; i < podaci.size(); ++i) delete podaci[i]; podaci.clear(); maks_objekata = s.maks_objekata; podaci.reserve(maks_objekata); for (int i = 0; i < s.podaci.size(); ++i) if (typeid(*s.podaci[i]) == typeid(Sanduk)) podaci.push_back(new Sanduk(*(Sanduk*)s.podaci[i])); else podaci.push_back(new Bure(*(Bure*)s.podaci[i])); } void Skladiste::DodajSanduk(double tezina, string naziv_predmeta, double tezina_predmeta, int broj_predmeta) { if (podaci.size() == maks_objekata) throw "Skladiste je popunjeno."; podaci.push_back(new Sanduk(tezina, naziv_predmeta, tezina_predmeta, broj_predmeta)); } void Skladiste::DodajBure(double tezina, string naziv_tecnosti, double tezina_tecnosti) { if (podaci.size() == maks_objekata) throw "Skladiste je popunjeno."; podaci.push_back(new Bure(tezina, naziv_tecnosti, tezina_tecnosti)); } Objekat& Skladiste::DajNajtezi() { if (podaci.size() == 0) throw "Skladiste je prazno."; int indeks_najtezeg = 0; for (int i = 1; i < podaci.size(); ++i) if (podaci[i]->DajTezinuPrazan() > podaci[indeks_najtezeg]->DajTezinuPrazan())

Page 86: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

indeks_najtezeg = i; return *podaci[indeks_najtezeg]; } Objekat& Skladiste::DajNajlaksi() { if (podaci.size() == 0) throw "Skladiste je prazno."; int indeks_najlakseg = 0; for (int i = 1; i < podaci.size(); ++i) if (podaci[i]->DajTezinuPrazan() < podaci[indeks_najlakseg]->DajTezinuPrazan()) indeks_najlakseg = i; return *podaci[indeks_najlakseg]; } int Skladiste::BrojTezihOd(double tezina) const { int broj_tezih_od = 0; for (int i = 0; i < podaci.size(); ++i) if (podaci[i]->DajTezinuPun() > tezina) ++broj_tezih_od; return broj_tezih_od; } void Skladiste::Ispisi() { sort(podaci.begin(), podaci.end(), Kriterij); cout << "Skladiste sadrzi sljedecih " << podaci.size() << " objekata:\n"; for (int i = 0; i < podaci.size(); ++i) podaci[i]->Ispisi(); } int main() { Skladiste s(10); ifstream fin("roba.txt"); while (true) { char c; fin >> c >> ws; if (fin.eof()) break; string naziv; getline(fin, naziv);

Page 87: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

if (c == 'S') { double tezina, tezina_predmeta; int broj_predmeta; fin >> tezina >> broj_predmeta >> tezina_predmeta; s.DodajSanduk(tezina, naziv, tezina_predmeta, broj_predmeta); } else { double tezina, tezina_tecnosti; fin >> tezina >> tezina_tecnosti; s.DodajBure(tezina, naziv, tezina_tecnosti); } fin.ignore(10009, '\n'); } s.Ispisi(); Skladiste s2(1); s2 = s; s2.Ispisi(); Skladiste s3(15); s3 = s; s3.Ispisi(); Skladiste s4(s); s4.Ispisi(); cout << "Najlaksi: "; s4.DajNajlaksi().Ispisi(); cout << "Najtezi: "; s4.DajNajtezi().Ispisi(); cout << "Broj tezih od 20 je: " << s4.BrojTezihOd(20) << endl; return 0; } Moguci izgled datoteke: S Tepsija 1.2 50 0.35 B Suncokretovo ulje 0.8 16.5 S Racunar 1.1 10 2.1 B Motorno ulje 1.5 35.1

Page 88: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

ZADAĆE Zadaća 1. Ova zadaća nosi ukupno 4 poena (od 20 poena, koliko će ukupno nositi sve zadaće zajedno), pri čemu svaki zadatak nosi po 0,8 poena. Svi zadaci se mogu uraditi na osnovu gradiva sa prva četiri predavanja i pretpostavljenog predznanja iz predmeta “Osnove računarstva”. Rok za predaju ove zadaće je utorak, 27. III 2012. (do kraja dana) i ne može se produžiti. Zadaće se predaju putem Zamgera. 1. U nekom deseterospratnom skladištu nalazi se lift za prevoz tereta koji se upravlja uz pomoć

računarskog programa. Trenutna pozicija lifta čuva se u promjenljivoj “sprat ” čije su legalne vrijednosti u opsegu od 0 do 10 (0 odgovara prizemlju). Trenutni smjer kretanja lifta (tj. smjer u kojem će se lift kretati nakon što se pokrene) čuva se u promjenljivoj “smjer ”. Ova promjenljiva je tipa “Smjerovi ”, koji predstavlja pobrojani tip definiran kao enum Smjerovi {Nagore, Nadolje};

Potrebno je napraviti program koji korisniku nudi sljedeće komande za upravljanje liftom: I – Idi; P – Promijeni smjer; K – Kraj. Komanda I obavezno je praćena jednim nenegativnim cijelim brojem (npr. I 5) i ona pomjera lift za navedeni broj spratova u smjeru u kojem je lift trenutno usmjeren. U slučaju da je nemoguće pomjeranje za zadani broj spratova, treba prijaviti poruku o greški. Komanda P mijenja smjer kretanja lifta, odnosno ukoliko se lift trenutno kreće nagore, nakon ove komande kretaće se nadolje, i obrnuto. Komanda K završava program. Sve druge komande su ilegalne, i trebaju dovesti do prijave greške i ponovnog izbora komande. Na početku rada, lift se nalazi u prizemlju i kreće se nagore. Dijalog između programa i korisnika mogao bi izgledati poput sljedećeg: Lift se nalazi u prizemlju i kre će se nagore. Unesi komandu (I – Idi, P – Promijeni smjer, K – Kr aj): I Pogrešna komanda (nedostaje parametar)! Unesi komandu (I – Idi, P – Promijeni smjer, K – Kr aj): I5 Lift se nalazi na 5. spratu i kre će se nagore. Unesi komandu (I – Idi, P – Promijeni smjer, K – Kr aj): I1 Lift se nalazi na 6. spratu i kre će se nagore. Unesi komandu (I – Idi, P – Promijeni smjer, K – Kr aj): P Lift se nalazi na 6. spratu i kre će se nadolje. Unesi komandu (I – Idi, P – Promijeni smjer, K – Kr aj): S Pogrešna komanda! Unesi komandu (I – Idi, P – Promijeni smjer, K – Kr aj): IXY2 Pogrešna komanda (neispravan parametar)! Unesi komandu (I – Idi, P – Promijeni smjer, K – Kr aj): I2XY Pogrešna komanda (neispravan parametar)! Unesi komandu (I – Idi, P – Promijeni smjer, K – Kr aj): I0 Lift se nalazi na 6. spratu i kre će se nadolje. Unesi komandu (I – Idi, P – Promijeni smjer, K – Kr aj): I-1 Pogrešna komanda (neispravan parametar)! Unesi komandu (I – Idi, P – Promijeni smjer, K – Kr aj): I8 Nije mogu će pomjeranje za navedeni iznos spratova! Unesi komandu (I – Idi, P – Promijeni smjer, K – Kr aj): I2 Lift se nalazi na 4. spratu i kre će se nadolje. Unesi komandu (I – Idi, P – Promijeni smjer, K – Kr aj): I4 Lift se nalazi u prizemlju i kre će se nadolje. Unesi komandu (I – Idi, P – Promijeni smjer, K – Kr aj): P2 Pogrešna komanda (suvišan parametar)! Unesi komandu (I – Idi, P – Promijeni smjer, K – Kr aj): P Lift se nalazi na 4. spratu i kre će se nagore. Unesi komandu (I – Idi, P – Promijeni smjer, K – Kr aj): KK Pogrešna komanda (suvišan parametar)!

Page 89: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

Unesi komandu (I – Idi, P – Promijeni smjer, K – Kr aj): K Dovidjenja! Naravno, konkretan dijalog zavisi od toga šta je korisnik unio, ali poruke koje se ispisuju na ekranu trebaju izgledati tačno kao što je u ovom dijalogu prikazano. Budite sigurno da ste predvidjeli ispravne reakcije na bilo šta što bi eventualno mogao unijeti korisnik (program ne smije da “crkne” ma šta korisnik unio). Napomena: funkcija “peek ” će Vam vjerovatno biti od velike koristi. 2. Napišite funkciju “SlikeUOgledalu ” koja kao parametar prima vektor cijelih brojeva a koja kao rezultat vraća novi vektor koji sadrži brojeve koji su “slika u ogledalu” odgovarajućih brojeva iz prvog vektora, odnosno koji se od odgovarajućih brojeva iz prvog vektora razlikuju po tome što im je redoslijed cifara obrnut. Na primjer, ukoliko se funkciji proslijedi vektor čiji su elementi redom 327, –42, 5, 46127, –319 i 87, vektor koji se vraća kao rezultat treba redom da sadrži elemente 723, –24, 5, 72164, –913 i 78. Napisanu funkciju demonstrirajte u testnom programu koji traži da se sa tastature unose brojevi koji se smještaju u neki vektor sve dok se sa tastature ne unese nula (koja se ne smješta u vektor), a koji nakon toga poziva napisanu funkciju da odredi “slike u ogledalu” unesenih brojeva i ispiše ih na ekran u vidu rečenica oblika “Slika u ogledalu broja x glasi y” i tako redom za sve brojeve. U programu ne treba testirati ispravnost unesenih podataka, tj. pretpostavićemo da će korisnik programa zaista unositi brojeve. Napomena: nikakav ispis ne treba vršiti unutar funkcije, nego samo u glavnom programu! 3. Napišite funkciju “BrojRijeci ” koja kao parametar prima jedan string (tj. parametar tipa “string ”) koji predstavlja neku rečenicu, a koja vraća kao rezultat broj riječi unutar te rečenice. Pri tome se pod pojmom “riječ” podrazumijeva svaka skupina susjednih znakova među kojima nema razmaka, takva da se ispred prvog znaka nalazi razmak (osim ukoliko se prvi znak nalazi na samom početku stringa) i da se iza posljednjeg znaka nalazi razmak (osim ukoliko se posljednji znak nalazi na samom kraju stringa). Na primjer, string “Ovo je primjer.” sastoji se od tri riječi, a isto vrijedi i za string “ Ovo je primjer. ”. Napisanu funkciju testirajte u glavnom programu na stringovima koji se unose sa tastature. 4. U teoriji brojeva često se javlja potreba da se neki prirodan broj n prikaže u obliku n = p q2 gdje su p i q prirodni brojevi takvi da p ima sve proste faktore različite (tj. u rastavi broja p na proste faktore niti jedan prosti faktor ne javlja se više puta, odnosno sa eksponentom većim od 1). Na primjer, imamo 28586250 = 42 ⋅ 8252, pri čemu 42 ima sve proste faktore različite (zaista, imamo 42 = 2 ⋅ 3 ⋅ 7). Ovakav prikaz nije teško dobiti nakon što prethodno rastavimo broj n na proste faktore. Na primjer, imamo ovakav račun: 28586250 = 2 ⋅ 33 ⋅ 54 ⋅ 7 ⋅ 112 = 2 ⋅ 3 ⋅ 32 ⋅ 54 ⋅ 7 ⋅ 112 = (2 ⋅ 3 ⋅ 7) ⋅ (32 ⋅ 54 ⋅ 112) = = (2 ⋅ 3 ⋅ 7) ⋅ (3 ⋅ 52 ⋅ 11)2 = 42 ⋅ 8252

Generalizirajte ovaj primjer tako što ćete napraviti funkciju “RastavaBroja ” sa tri parametra “n”, “ fmin ” i “ fmax ” koja za zadani prirodan broj n (koji se zadaje kao prvi parametar “n” ove funkcije) pronalazi rastavu oblika n = p q2 pri čemu p zadovoljava postavljene uvjete i nađene vrijednosti p i q smješta respektivno u parametre “p” i “ q”. Na primjer, ukoliko se kao prvi parametar zada broj 28586250, u drugi i treći parametar treba da se smjeste respektivno brojevi 42 i 825. U slučaju da n nije prirodan broj, funkcija treba baciti izuzetak. Funkcija se u svom radu ne treba oslanjati ni na kakve druge funkcije. Napisanu funkciju demonstrirajte u testnom programu u kojem se za broj unesen sa tastature ispisuje odgovarajuće brojeve p i q. Program treba da testira da li je korisnik zaista unio broj i da prijavi odgovarajuću poruku o greški ukoliko to nije slučaj. Obavezno predvidite i hvatanje eventualno bačenog izuzetka. Napomena 1: prosti brojevi su, za onog ko to ne zna (a praksa pokazuje da ima dosta onih koji to ne znaju), oni brojevi koji imaju tačno dva djelioca, jedinicu i samog sebe. Prosti faktori nekog broja su oni njegovi faktori koji su prosti brojevi. Napomena 2: Dozvoljeno je u nekim slučajevima da bude p = 1 (to će se desiti kad god je n kvadrat nekog cijelog broja, npr. 15876 = 1 ⋅ 1262) mada, strogo rečeno, broj 1 nema prostih faktora pa je malo diskutabilno reći da su “svi njegovi prosti faktori različiti”.

Page 90: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

5. Neki element matrice naziva se njen lokalni minimum ukoliko je on striktno manji od svih ostalih elemenata koji se nalaze u istom redu ili u istoj koloni kao i taj element. Analogno se definira i lokalni maksimum. Može se desiti da matrica uopće nema lokalnih minimuma ili maksimuma, a može se desiti da ih ima više od jednog. Na primjer, sljedeća matrica ima tri lokalna minimuma (to su elementi na pozicijama (1,3), (2,4) i (4,1)) i dva lokalna maksimuma (to su elementi na pozicijama (1,5) i (2,2)):

Napišite funkciju “EkstremiMatrice ” koja kao prvi parametar prima matricu realnih brojeva organiziranu kao vektor vektôrā realnih brojeva, a koja u drugi i treći parametar smješta respektivno broj lokalnih minimuma i broj lokalnih maksimuma matrice. Ukoliko preneseni parametar nema strukturu matrice (tj. ukoliko svi redovi proslijeđenog vektora vektôrā nemaju isti broj elemenata), funkcija treba baciti izuzetak. Napisanu funkciju testirajte u glavnom programu na primjeru matrice čije se dimenzije i elementi unose sa tastature. Pri tome ćemo pretpostaviti da će uneseni podaci biti korektni, odnosno ne treba testirati ispravnost unesenih podataka. Napomena: u ovom konkretnom programu, izuzetak nikada neće biti bačen, s obzirom da će se funkciji iz glavnog programa uvijek prenositi ispravni parametri (tj. parametri koji zaista imaju strukturu matrice). Međutim, s obzirom da dobro napisana funkcija ne treba ništa da zna o tome u kakvom će okruženju biti korištena, funkcija mora da se zna “odbraniti” u slučaju da u nju ipak “uđu” neispravni podaci. 1.POZNATI LIFT :D #include <iostream> using namespace std; int main() { enum Spratovi{Prizemlje, Prvi, Drugi, Treci, Cetvrti, Peti, Sesti, Sedmi, Osmi, Deveti, Deseti}; enum Smjerovi{Nagore, Nadolje}; Smjerovi smjer(Nagore); Spratovi sprat(Prizemlje); cout<<"Lift se nalazi u prizemlju i krece se nagore."<<endl; int s; //s kao sprat char k; //k kao komanda koju korisnik odabere while (k!='K') { cout<<"Unesi komandu (I-Idi, P-Promijeni smjer, K-Kraj):"; cin>>k; //Provjera uvjeta za prvi znak

Page 91: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

while ((k!='I')&&(k!='P')&&(k!='K')) { cout<<"Pogresan unos komande, parametri nisu ispravni!*"<<endl; cin.ignore(10000,'\n'); cout<<"Unesi komandu (I-Idi, P-Promijeni smjer, K-Kraj):"; cin>>k; } //Uvjeti za smjer kretanja if (k=='P') { if (smjer==Nagore) { smjer=Nadolje; cout<<"Lift se nalazi na "<<sprat<<". spratu i krece se nadolje."<<endl; } else { smjer=Nagore; cout<<"Lift se nalazi na "<<sprat<<". spratu i krece se nagore."<<endl; } } if (k=='I') { if (cin.peek()==' ') { cout<<"Pogresan unos komande, parametri nisu ispravni!!!"<<endl; cin.ignore(10000,'\n'); continue; } cin>>s; //Uvjeti za sprat if (cin.peek()=='.') { cout<<"Pogresan unos komande, parametri nisu ispravni!!!"<<endl; cin.ignore(10000,'\n');

Page 92: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

continue; } while (!cin) { cout<<"Pogresan unos komande, parametri nisu ispravni!"<<endl; cin.clear(); cin.ignore(100000,'\n'); continue; /* cout<<"Unesi komandu (I-Idi, P-Promijeni smjer, K-Kraj):*"; cin>>k;*/ } if (s<0) { cout<<"Neispravan parametar."<<endl; cin.ignore(100,'\n'); continue; } else { if (((sprat+s)>10)&&(smjer==Nagore)) { cout<<"Neispravan parametar!!!"<<endl; continue; } if (((sprat-s)<0)&&(smjer==Nadolje)) { cout<<"Neispravan parametar!!!"<<endl; continue; } if (smjer==Nagore) { sprat=Spratovi(sprat+s); cout<<"Lift se nalazi na "<<sprat<<". spratu i krece se nagore."<<endl; } if (smjer==Nadolje)

Page 93: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

{ sprat=Spratovi(sprat-s); cout<<"Lift se nalazi na "<<sprat<<". spratu i krece se nadolje."<<endl; } } } } cout<<"Dovidjenja!"<<endl; return 0; } 2.SLIKE U OGLEDALU #include <iostream> #include <vector> #include<cmath> using namespace std; vector<int> SlikeUOgledalu ( vector<int> niz ) { vector<int>Odraz; Odraz.resize(niz.size()); int k(0); for (int i=0;i<niz.size();i++) { k=niz[i];//Pomocna varijabla, jer ne zelim jos "unistiti" vrijednost niz[i], treba mi samom da prebrojim cifre int cifre(0); while (abs(k)>0) { k=k/10; cifre++; } int suma(0); //Okrecem cifre, pazeci na tezinske nosioce cout<<cifre<<endl; for (int h=(cifre-1);h>=0;h--) {

Page 94: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

suma=suma+(niz[i]%10)*pow(10.,h); niz[i]/=10; } //Novodobijeni broj smjestam u novi vektor Odraz[i]=suma; } return Odraz; } int main() { vector<int>niz; int elemenat; cout<<"Unesite elemente vaseg niza->"<<endl; //Unos elemenata vektora for (;;) { cin>>elemenat; if (elemenat==0)break; niz.push_back(elemenat); } vector<int>niz2(niz.size()); //Poziv funkcije niz2 = SlikeUOgledalu ( niz ); for (int i=0;i<niz.size();i++) { cout<<"Slika u ogledalu broja "<<niz[i]<<" glasi "<<niz2[i]<<"."<<endl; } return 0; } 3.BROJ RIJEČI #include <iostream> #include <string>

Page 95: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

using namespace std; int BrojRijeci(string recenica) { int brojac(0); for (int i=0;i<recenica.length();i++) { if (recenica[i]==' ') { brojac++; while (recenica[i]==' ')i++; } if ((recenica[i]=='.')&&(recenica[i+1]==' '))//Ako poslije tacke ima bjelina brojac--; } if (recenica[0]==' ')brojac--;//Kad recenica pocinje razmakom return brojac+1;//Kad nema razmaka na samom pocetku } int main() { string recenica; cout<<"Unesite vasu recenicu->"<<endl; getline(cin,recenica); int rijeci; rijeci=BrojRijeci(recenica); cout<<endl<<"Broj rijeci u vasoj recenici->"<<rijeci; return 0; } 4.PROSTI FAKTORI

Page 96: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

#include <iostream> #include<vector> using namespace std; void RastavaBroja( int n, int &fmin, int &fmax) { vector<int>faktori; int pom(n); for (int i=0;i<n;i++) { if (pom%i==0) { faktori.push_back(i); pom/=i; i--; } } int i(0); while(i<faktori.size()) { int brojac(0), j(i); while(faktori[j]==faktori[i]) { brojac++; i++; } if(brojac%2==1) fmin*=faktori[j]; } } int main() { cout<<"Unesite svoj prirodan broj->"<<endl; int n; cin>>n; while (!cin) {

Page 97: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

cout<<"Niste unijeli prirodan broj!"<<endl<<"Unesite prirodan broj->"<<endl; cin.clear(); cin.ignore(10000,'\n'); cin>>n; } int fmin(1), fmax(1); RastavaBroja(n,fmin,fmax); return 0; } 5.MINMAX #include <iostream> #include <vector> #include <iomanip> using namespace std; void EkstremiMatrice( vector<vector<double> > matrica,int &min,int &max) { int greska(0); //Provjera za matricu for (int i=0;i<matrica.size();i++) { if ((matrica[0].size())!=(matrica[i].size()))throw greska ; } //Potraga za maksimumima i minimumima for (int i=0;i <matrica.size();i++) { for ( int j=0;j <matrica[0].size();j++) { bool postoji_minimalni(true), postoji_maksimalni(true); for (int n=0;n<matrica[0].size();n++) { if ((matrica[i][j]>=matrica[i][n])&&(j!=n))postoji_minimalni=false; if ((matrica[i][j]<=matrica[i][n])&&(j!=n))postoji_maksimalni=false; } for (int k=0; k<matrica.size();k++) { if ((matrica[i][j]>=matrica[k][j])&& (i!=k))postoji_minimalni=false; if ((matrica[i][j]<=matrica[k][j])&&(i!=k))postoji_maksimalni=false;

Page 98: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

} if (postoji_minimalni)min++; if (postoji_maksimalni)max++; } } } int main() { try { cout<<"Unesite dimenzije matrice:"<<endl<<"Broj redova->"; int redovi, kolone; cin>>redovi; cout<<"Broj kolona->"; cin>>kolone; vector<vector<double> > matrica(redovi,vector<double>(kolone)); cout<<"Unesi elemente matrice:"<<endl; for (int i=0;i<redovi;i++) { for (int j=0; j<kolone; j++) { cout<<"Elemenat ("<<i+1<<","<<j+1<<")->"<<endl; cin>>matrica[i][j]; } } for (int i=0;i<redovi;i++) { for (int j=0; j<kolone; j++) { cout<<setw(8)<<matrica[i][j]; } cout<<endl<<endl; } int max(0), min(0); EkstremiMatrice(matrica,min, max); cout<<"Ova matrica ima "<<min<<" lokalnih minimuma."<<endl;

Page 99: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

cout<<"Ova matrica ima "<<max<<" lokalnih maksimuma."<<endl; } catch (...) { cout<<"Vas proslijedjeni vector nije matrica!"; } return 0; }

Zadaća 2. Ova zadaća nosi ukupno 4 poena, pri čemu svaki zadatak nosi po 0,8 poena. Svi zadaci se mogu uraditi na osnovu gradiva sa prvih šest predavanja i pretpostavljenog predznanja iz predmeta “Osnove računarstva”. Rok za predaju ove zadaće je petak 13. IV 2012. (do kraja dana) i ne može se produžiti. Zadaće se predaju putem Zamgera. Pitanje: Da li je moguće produžiti rok za predaju zadaće do nedjelje, 15. IV 2012. s obzirom da je ispit u ponedjeljak, 16. IV 2012? Odgovor: Ne. Pitanje: Zašto? Odgovor: Baš zato što je ispit u ponedjeljak, 16. IV 2012. Zadaća se ne radi dan pred ispit. A ni dva dana pred ispit. Posljednja dva dana pred ispit trebaju se iskoristiti na bolji način nego izradom zadaće. Pitanje: A ne možete odgoditi ni zbog činjenice da se petak 13. smatra baksuznim danom? Odgovor: Ne može... Niste valjda toliko sujevjerni!? Pitanje: Da li je ovo konačan stav? Odgovor: Da (evo i jednog afirmativnog odgovora). VAŽNA NAPOMENA: Postoji mogućnost da će se neki zadaci testirati automatskim testnim skriptama. Da bi takvo testiranje ispravno radilo, sve funkcije se MORAJU ZVATI TAČNO ONAKO KAKO JE SPECIFICIRANO i moraju primati TAČNO ONAKVE PARAMETRE KAKO JE SPECIFICIRANO. U suprotnom će testna skripta odbaciti zadatak kao neispravan!!! 1. Napišite generičku funkciju “OdstraniZadaneElemente ” koja ima dva parametra “v” i “ v1 ”. Oba parametra su vektori proizvoljnog ali istog tipa elemenata (tj. tip elemenata u oba vektora je isti) za koje se pretpostavlja da se mogu porediti. Funkcija treba da iz vektora “v” odstrani sve elemente koji se nalaze i u vektoru “v1 ”, zadržavajući ostale elemente u istom poretku kakvi su bili prije odstranjivanja. Funkcija ne vraća nikakvu vrijednost, već samo utiče na elemente parametra “v” (koji pri tome, naravno, može promijeniti svoju veličinu). Na primjer, ako prije poziva funkcije vektor “v” sadrži redom elemente 3, 8, 5, 6, 1, 4, 9, 7, 2, 2, 6, 4, 9, 1, 4, 8, 3, 6 i 5, a vektor “v1 ” elemente 4, 0, 3, 4 i 2, nakon poziva funkcije vektor “v” treba da sadrži redom elemente 8, 5, 6, 1, 9, 7, 6, 9, 1, 8, 6 i 5. Pri tome, funkcija ne smije u svom radu kreirati i koristiti nikakve druge vektore ili nizove osim samih parametara “v” i “ v1 ” (tj. nije dozvoljeno koristiti nikakve pomoćne vektore). Također, nije dozvoljeno koristiti nikakve bibliotečke funkcije čija upotreba nije bila demonstrirana na predavanjima (poput funkcije “erase ” primijenjene na vektore). Napisanu funkciju demonstrirajte u testnom programu koji će iz spiska kompleksnih brojeva koji se unose sa tastature (te kompleksne brojeve treba čuvati u vektoru čiji su elementi kompleksni brojevi) odstraniti sve kompleksne brojeve sa drugog spiska kompleksnih brojeva koji se također unosi putem tastature i ispisati sve kompleksne brojeve iz prvog spiska nakon obavljenog odstranjivanja. 2. Napišite program koji od korisnika traži da unese dimenzije pravougaone matrice n i m a zatim da unese dvije matrice formata n ×m (pretpostavite da su elementi matrica realni brojevi). Program

Page 100: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

nakon toga treba da ispiše produkt dvije unesene matrice. Program treba da bude zasnovan na skupini napisanih funkcija za rad sa matricama, koje radi univerzalnosti treba izvesti kao generičke funkcije (bez obzira što će se u ovom programu raditi samo sa matricama čiji su elementi realni brojevi). U programu treba da se nalaze sljedeće funkcije: “KreirajMatricu ”, “UnesiMatricu ”, “ PomnoziMatrice ”, “ IspisiMatricu “ i “ UnistiMatricu ”. Funkcija “KreirajMatricu “ prima kao parametre dvojni pokazivač koji služi za pristup dinamički kreiranoj matrici (u nastavku ćemo ovaj pokazivač prosto zvati dinamička matrica), kao i dimenzije matrice n i m. Funkcija treba da alocira prostor za matricu formata n × m i dodijeli adresu alociranog prostora pokazivaču koji se koristi za pristup njenim elementima. Funkcija “UnesiMatricu ” popunjava matricu elementima unesenim sa tastature, a prima kao parametre dinamičku matricu i dimenzije n i m. Funkcija “PomnoziMatrice ” prima kao parametre dvije dinamičke matrice i njihove dimenzije n1 i m1, odnosni n2 i m2. Ova funkcija treba da kreira novu dinamičku matricu (pozivom funkcije “KreirajMatricu ”), da je popuni proizvodom dvije dinamičke matrice koje su joj proslijeđene kao parametri, i da vrati kao rezultat dvojni pokazivač koji služi za pristup elementima novokreirane matrice. U slučaju da matrice nisu saglasne za množenje, funkcija treba da baci izuzetak. Funkcija “ IspisiMatricu ” kao parametre prima dinamičku matricu, dimenzije n i m kao i željenu širinu ispisa, a ispisuje elemente matrice na ekran, pri čemu se svaki element matrice ispisuje u skladu sa zadanom širinom ispisa. Konačno, funkcija “UnistiMatricu ” unistava dinamički kreiranu matricu koja joj se prosljeđuje kao parametar (zajedno sa dimenzijama n i m). Funkcija “KreirajMatricu ” treba da baci izuzetak u slučaju da kreiranje ne uspije. Pri tome, ova funkcija mora da vodi računa da u slučaju da dođe do bacanja izuzetka “počisti iza sebe” sve uspjele alokacije, tako da ne dođe do curenja memorije. Eventualno bačene izuzetak treba hvatati u glavnom programu. Obavezno testirajte slučaj kada alokacija ne uspijeva (unosom prevelikih brojeva n i/ili m). 3. Na predavanjima je obrađeno nekoliko korisnih funkcija iz biblioteke “algorithm ”. Među njima su i funkcije “min element ”, “ reverse ” i “ find if ” i “ replace copy if ”. Napišite vlastite verzije ovih funkcije nazvane “Najmanji ”, “ Izvrni ”, “ NadjiUvjetno ” i “KopirajUzZamjenuUvjetno ”, koje rade potpuno istu stvar kao i odgovarajuće bibliotečke funkcije. Funkcije treba realizirati isključivo korištenjem pokazivačke aritmetike. Bitno je da sve funkcije moraju biti zasnovane na potpunoj dedukciji tipova, tako da ispravno rade i sa pokazivačima i sa iteratorima. Ove funkcije testirajte u glavnom programu koji će: • Unijeti sa tastature n cijelih brojeva i smjestiti ih u dek, pri čemu se n također unosi sa tastature; • Umanjiti najmanji broj u deku za 1 (ukoliko ima više najmanjih brojeva, treba umanjiti samo prvi od njih); • Ispisati koji je prvi element u deku (nakon modifikacije obavljene u prethodnoj stavci) koji ima barem jednu parnu cifru u sebi (npr. broj 3527) i na kojoj se poziciji u deku nalazi (ukoliko takvog elementa nema, treba ispisati odgovarajuću poruku koja govori o tome); • Izvrnuti sve elemente deka, tako da prvi element postane posljednji, itd. • Iskopirati sve elemente tako izvrnutog deka u dinamički alocirani niz od n cijelih brojeva, uz zamjenu onih elemenata koji su prosti brojevi nulama; • Ispisati na ekran sve elemente tako formiranog niza; • Osloboditi memoriju koju je zauzimao dinamički alocirani niz. U glavnom programu nije dozvoljeno koristiti petlje (osim za unos i ispis elemenata niza), već

sve manipulacije treba ostvariti isključivo pozivima napisanih funkcija. Isto tako, niti jedna funkcija unutar svog tijela ne smije koristiti nikakve dodatne kontejnerske tipove podataka (nizove, vektore, dekove, itd.). Napomena 1: Iako na prvi pogled tako ne izgleda, potpuna dedukcija može prilično usložniti implementaciju nekih od traženih funkcija. Jednu od njih čak nećete moći implementirati bez da napišete jednu pomoćnu funkciju (također generičku) koju ćete pozivati iz nje (što naravno nije

Page 101: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

zabranjeno). Sami ćete uvidjeti zašto. Napomena 2: Pokazivačka aritmetika ne radi nužno ispravno sa dekovima, s obzirom da ne postoji garancija da su susjedni elementi deka zaista i susjedni u memoriji. Stoga se za rad sa dekovima moraju koristiti iteratori. Vodite računa o tome. Napomena 3: Kao test da li Vam napisane funkcije rade ispravno, Vaš glavni program treba identično raditi ukoliko pozive funkcija “Najmanji ”, “ Izvrni ”, “ NadjiUvjetno ” i “KopirajUzZamjenuUvjetno ” zamijenite pozivima odgovarajućih bibliotečkih funkcija. 4. Napravite funkciju “SortirajRecenice ” koja kao parametar prima pokazivač koji pokazuje na prvi element nekog dinamički alociranog niza stringova (preciznije niza čiji su elementi tipa “string ”) kao i broj elemenata u tom nizu. Funkcija treba da sortira razmatrani niz stringova u takav poredak u kojem će se duže rečenice nalaziti uvijek ispred kraćih. U slučaju da dvije rečenice imaju istu dužinu, tada rečenica koja dolazi prije po abecednom poretku treba da dođe ispred rečenice koja dolazi kasnije po abecednom poretku (pri tome ne treba praviti razliku između malih i velikih slova). Sortiranje treba obaviti uz pomoć bibliotečke funkcije “sort ” (uz definiranje odgovarajuće funkcije kriterija). Napisanu funkciju treba demonstrirati u testnom programu koji prvo traži da se sa tastature unese prirodan broj n, nakon čega dinamički alocira niz od n stringova i popunjava ih sa n rečenica unesenih sa tastature. Program zatim sortira niz u traženi poredak pozivom napisane funkcije. Nakon obavljenog sortiranja, sortirani niz treba ispisati na ekran. Na kraju, program treba da za novu riječ unesenu sa tastature postupkom binarne pretrage ustanovi da li se nalazi u razmatranom nizu ili ne (podrazumijeva se ispis odgovarajućeg komentara o tome) i da nakon toga obriše dinamički alocirani niz. Binarnu pretragu treba obaviti uz pomoć odgovarajuće bibliotečke funkcije. Dobro obratite pažnju da niz nije sortiran u uobičajenom poretku – funkcija za obavljanje binarne pretrage to mora uzeti u obzir! 5. Napišite program koji će Vas uvjeriti koliko je bolje koristiti bibliotečku funkciju “sort ” od ručnog sortiranja. U programu ćete prvo definirati dvije funkcije “GenerirajNiz ” i “SortirajRucno ”. Funkcija “GenerirajNiz ” treba da ima jedan cjelobrojni parametar “n” i ona dinamički alocira niz od “n” elemenata popunjen slučajnim realnim brojevima iz opsega od 0 do 1 i vraća kao rezultat pokazivač na prvi element tako kreiranog niza. Za generiranje slučajnih brojeva koristite funkciju “rand ” bez parametara iz biblioteke “cstdlib ” koja kao rezultat vraća slučajan cijeli broj u opsegu od 0 do neke velike vrijednosti nazvane “RAND_MAX” a koja je ovisna od implementacije, tako da ćete dijeljenjem vrijednosti koje vrati funkcija “rand ” sa ovom vrijednošću sigurno dobiti broj u opsegu od 0 do 1 (oprez: čuvajte se cjelobrojnog dijeljenja). Funkcija “SortirajRucno ” ima dva parametra koji redom predstavljaju pokazivač na prvi element i pokazivač iza posljednjeg elementa bloka koji se sortira (identično kao bibliotečka funkcija “sort ”). Ova funkcija vrši sortiranje bloka u opadajući poredak koristeći neki od jednostavnih postupaka za sortiranje koji su Vam poznati (npr. BubbleSort, SelectionSort, itd.). Funkcija bi trebala da bude generička, tako da može sortirati u opadajući poredak niz elemenata proizvoljnog tipa uz pretpostavku da se oni mogu međusobno porediti (mada ćete je u ovom programu koristiti samo za sortiranje niza realnih brojeva). Napisane funkcije ćete iskoristiti u testnom programu koji prvo definira dvije cjelobrojne konstante “n1” i “ n2” (čije ćete tačne vrijednosti odrediti kasnije) a koji zatim dinamički kreira dva niza sa respektivno “n1” i “n2” elemenata. Nakon toga, prvi niz treba sortirati pozivom funkcije “SortirajRucno ”, a drugi pozivom bibliotečke funkcije “sort ” (uz odgovarajuću funkciju kriterija, s obzirom da se traži sortiranje u opadajućem poretku). Testiranje započnite od malih vrijednosti “n1” i “ n2”, a zatim povećavajte ove vrijednosti sve dok trajanje svakog od sortiranja bude trajalo približno 10 sekundi. Uporedite ove vrijednosti i sami izvucite zaključak. Napomena: Finalna verzija programa ne treba da traži nikakav unos podataka sa tastature (konstante “n1” i “ n2” trebaju da budu hard-kodirane, tj.fiksno upisane u program)!

Page 102: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

1.BRISANJE #include <iostream> #include <complex> #include<vector> using namespace std; template < typename TIP> void OdstraniZadaneElemente( vector<TIP> &v1,vector<TIP> &v2) { for (int i=0;i<v1.size();i++) { for (int j=0;j<v2.size();j++) { if (v1[i]==v2[j])v1[i]=TIP(); } } //prebacim na kraj "nulirane" elemente i "izbrisem" ih smanjivši velicinu vektora int b(0); for (int i=0;i<v1.size();i++) { if (v1[i]==TIP()) { b++; for (int j=i;j<v1.size()-1;j++) { v1[j]=v1[j+1]; } } } v1.resize(v1.size()-b); } int main() { //Posto u zadatku nije naveden uvjet za kraj unosa, prvo korisnik unosi broj elemenata niza cout<<"Unesite vas broj elemenata vektora->"<<endl; int n; cin>>n; //Dodala sam uvjete za pogresan unos podataka iako nije navedeno u zadataku jer blokada pri unosu slova najcesca

Page 103: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

while (n<0) { cin.ignore(1000,'\n'); cout<<"Niste unijeli pozitivan prirodan broj, unesite ponovo->"<<endl; cin>>n; } while (!cin) { cout << "Niste unijeli broj!!!" << endl<<"Unesite ponovo->"; cin.clear(); cin.ignore(1000,'\n'); cin>>n; } //unos elemenata vektora cout << "Unesite elemente vaseg vektora->" << endl << "Obratite paznju na nacin unosenja kompleksnih brojeva!"<<endl; vector< complex<double> > niz(n); for (int i=0; i<n; i++) { cout<<i+1<<".elemenat->"; cin>>niz[i]; while (!cin) { cout << "Niste unijeli broj!!!" << endl<<endl<<"Unesite ponovo->"<<endl<<i+1<<".elemenat->"; cin.clear(); cin.ignore(1000,'\n'); cin>>niz[i]; } } cout<<"Unesite broj elemenata koje zelite izbrisati iz vektora->"; int m; cin>>m; while (!cin) { cout << "Niste unijeli broj!!!" << endl<<"Unesite ponovo->"; cin.clear(); cin.ignore(1000,'\n'); cin>>m; } //unos elemenata koje zelimo izbrisati iz prethodnog vektora

Page 104: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

cout<<"Unesite elemente koje zelite izbrisati iz niza->"<<endl; vector< complex <double> > niz2(m); for (int i=0;i<m;i++) { cout<<i+1<<".elemenat->"; cin>>niz2[i]; while (!cin) { cout << "Niste unijeli broj!!!" << endl<<"Unesite ponovo->"<<i+1<<".elemenat->"; cin.clear(); cin.ignore(1000,'\n'); cin>>niz2[i]; } } OdstraniZadaneElemente(niz,niz2); //ispis unesenih vektora radi provjere ispravnosti unesenih podataka i rada same funkcije for (int j=0;j<niz.size();j++)cout<<endl<<niz[j]<<endl; return 0; } 2.MATRICE #include <iostream> #include <iomanip> using namespace std; template<typename Tip> void UnistiMatricu(Tip **&dinamicka,int n,int m) { if (dinamicka==0)return; for (int i=0;i<n;i++) delete[] dinamicka[i]; delete[] dinamicka; } template <typename Tip> void UnesiMatricu(Tip **&dinamicka, int n, int m) {

Page 105: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

for (int i=0; i<n;i++) { for (int j=0;j<m; j++) { cout << "Elemenat[" << i+1 << "][" << j+1 << "]->" << endl; cin >> dinamicka[i][j]; } } } template < typename Tip> void KreirajMatricu(Tip **&dinamicka, int n, int m) { try { dinamicka=new Tip*[n]; for (int i=0;i<n;i++) dinamicka[i] = new Tip [m]; } catch (...) { UnistiMatricu(dinamicka,n,m); throw; } } template<typename Tip> Tip** PomnoziMatrice(Tip **dinamicka1,Tip**dinamicka2,int n1, int m1, int n2,int m2) { if (m1!=n2)throw "Matrice nisu saglasne za mnozenje"; Tip **produkt(0); KreirajMatricu(produkt,n1,m2); for (int i=0;i<n1;i++) { for (int j=0;j<m2;j++) { produkt[i][j]=0;

Page 106: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

for (int k=0;k<m1;k++) produkt[i][j]+=dinamicka1[i][k]*dinamicka2[k][j]; } } return produkt; } template<typename Tip> void IspisiMatricu(Tip **matrica,int n,int m,int d) { for (int i=0; i<n ;i++) { for (int j=0 ;j<m ;j++)cout<<setw(d)<<matrica[i][j]; cout<<endl; } } int main() { cout << "Unesite dimenzije vase prve matrice->" << endl <<"n->"<<endl; int n1(0),m1(0); cin>>n1; cout<< "m->" <<endl; cin>>m1; double **matrica1; try { KreirajMatricu(matrica1,n1,m1); } catch (...) { cout<<"Greska."<<endl; } cout << "Unesite elemente vase prve matrice->" << endl; UnesiMatricu(matrica1,n1,m1); cout<<"Unesite dimenzije vase druge matrice->"<<endl<<"n->"<<endl; int n2(0),m2(0); cin>>n2; cout<<"m->"<<endl; cin>>m2;

Page 107: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

double **matrica2(0); try { KreirajMatricu(matrica2,n2,m2); } catch (...) { cout<<"Greska!"<<endl; } cout<<"Unesite elemente vase druge matrice->"<<endl; UnesiMatricu(matrica2,n2,m2); double **Produkt(0); try { Produkt=PomnoziMatrice(matrica1,matrica2,n1,m1,n2,m2); } catch (const char poruka[]) { cout<<poruka; } IspisiMatricu(Produkt,n1,m2,4); UnistiMatricu(Produkt,n1,m2); UnistiMatricu(matrica1,n1,m1); UnistiMatricu(matrica2,n2,m2); return 0; } 3.ALGORITHM #include <iostream>

Page 108: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

#include <deque> using namespace std; bool Prost (int n) { for (int i=2;i<n;i++) { if (n%i==0)return false; } return true; } template <typename pok, typename pokdr,typename tip> void KopirajUvjetno(pok p1, pok p2, pokdr p3, bool funkcija(tip), tip v) { while (p1!=p2) { if (funkcija(*p1)) { *p1=v; } *p3++=*p1++; } } //funkcija koja provjerava da su cifre parne bool Parni(int n) { while (n!=0) { if ((n%10)%2==0) { return true; } n/=10; };

Page 109: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

return false; } //find if template <typename pok,typename tip> pok NadjiUvjetno( pok p1, pok p2, bool f(tip)) { while (p1!=p2) { if (f(*p1))return p1; p1++; } return p2; } template<typename tip> void pomocna(tip &p,tip &k) { tip pom(p); p=k; k=pom; } //reverse template<typename pok> void Izvrni(pok p, pok k) { k--; while (p<=k)//important jer se radi o iteratorima { pomocna(*p,*k); p++; k--; } } //min_element template<typename tippok1> tippok1 Najmanji(tippok1 n, tippok1 m) { tippok1 min(n); while (n!=m) { if (*n<*min)min=n;

Page 110: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

n++; } return min; } //max_element template <typename tippok1> tippok1 Najveci(tippok1 n,tippok1 m) { tippok1 maks(n); while (n!=m) { if (*n>*maks)maks=n; n++; } return maks; } int main() { //unnos elemenata deka cout << "Koliko elemenata deka unosite?" << endl; int n; cin >> n; cout << "Unesite elemente vaseg deka->"<<endl; deque <int> dek(n); for (int i=0;i<n;i++) { cout<<i+1<<".->"; cin>>dek[i]; } deque<int>::iterator p; //min_element p=Najmanji(dek.begin(),dek.end()); *p=*p-1; cout<<"Najmanji broj deka umanjen za jedan->"<<*p<<endl; //find_if p=NadjiUvjetno(dek.begin(),dek.end(),Parni); if (p==dek.end())cout<<"Nema broja sa parnom cifrom."; else cout<<"Nas prvi elemenat s parnom cifrom->"<<*p<<endl;

Page 111: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

//reverse cout<<"Izvnuti niz->"<<endl; Izvrni(dek.begin(),dek.end()); for (int i=0;i<dek.size();i++) { cout<<dek[i]<<endl; } //replace_copy_if int *nizpok(new int [n]); KopirajUvjetno(dek.begin(),dek.end(),nizpok,Prost, 0); cout<<"Niz bez prostih brojeva."<<endl; for (int i=0;i<n;i++) { cout<<nizpok[i]<<endl; } delete [] nizpok; nizpok=0; return 0; } 4.RECENICE #include <iostream> #include <string> #include <algorithm> using namespace std; void Poistovjeti(string &n) { for(int i=0;i<n.size();i++) { if(n[i]>='a'&&n[i]<='z')n[i]=n[i]+'A'-'a';} } bool Kriterij( string a, string b) {Poistovjeti(a); Poistovjeti(b); if(a.size()==b.size())return a<b; return a.size()>b.size(); }

Page 112: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

int main() { cout<<"Koliko recenica zelite unijeti?"<<endl; int n; cin>>n; cin.ignore(1000,'\n'); string *recenice(new string[n]); for(int i=0;i<n;i++) {getline(cin,recenice[i]); } sort(recenice,recenice+n,Kriterij); for(int i=0;i<n;i++) {cout<<recenice[i]<<endl;} return 0; } 5.SORTIRANJE #include <iostream> #include<algorithm> #include<cstdlib> using namespace std; double *GenerirajNiz(int n) { double *p(new double[n]); for(int j=0; j<n; j++) { *(p+j)=double(rand())/RAND_MAX; } return p; } template<typename TIP> void SortirajRucno(TIP *p1, TIP *p2) { for(int i=0; i<(p2-p1+1); i++) { for(int j=i+1; j<(p2-p1+1); j++) { TIP pom;

Page 113: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

if(p1[j]>p1[i]) { pom=p1[j]; p1[j]=p1[i]; p1[i]=pom; } } } } bool Kriterij(double a, double b) { return a>b; } int main() { const int n1(800),n2(800); double *niz1(GenerirajNiz(n1)); double *p12(niz1+n1); double *niz2(GenerirajNiz(n2)); SortirajRucno(niz1, p12); cout<<"Prvi sortirani niz(SortirajRucno:)"<<endl; for(int i=0; i<n1; i++) { cout<<niz1[i]<<endl; } sort(niz2,niz2+n2,Kriterij); cout<<endl<<"Drugi sortirani niz:(funkcija sort)"<<endl; for(int i=0; i<n2; i++) { cout<<niz2[i]<<endl; } delete[] niz1; delete[] niz2; return 0; }

Zadaća 3.

Page 114: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

Ova zadaća nosi ukupno 4 poena, pri čemu prvi zadatak nosi 0.7 poena, drugi 1 poen, treći i četvrti po 0.6 poena i peti 1.1 poen. Svi zadaci se mogu uraditi na osnovu gradiva sa prvih 9 predavanja i pretpostavljenog predznanja iz predmeta “Osnove računarstva”. Rok za predaju ove zadaće je utorak, 8. V 2012. (do kraja dana) i ne može se produžiti. Zadaće se predaju putem Zamgera. 1. Dopunite program “matrica struct.cpp ” priložen uz Predavanje 7. sa dvije nove funkcije “ProduktMatrica ” i “ StepenMatrica ”. Funkcija “ProduktMatrica ” prima dvije matrice kao parametre (matrice su definirane kao odgovarajuće strukture) i vraća njihov produkt kao rezultat, odnosno baca izuzetak ukoliko matrice nisu saglasne za množenje. Funkcija “StepenMatrica ” prima matricu kao jedan parametar, kao drugi parametar prima prirodan broj n, i kao rezultat vraća matricu dignutu na n-ti stepen (u matričnom smislu) odnosno baca izuzetak ukoliko matrica nije kvadratna, s obzirom da je stepen matrice definiran samo za kvadratne matrice (pri realizaciji ove funkcije možete koristiti već napisanu funkciju “ProduktMatrica ”). Također, proširite funkciju “IspisiMatricu ” dodatnim parametrom “treba_brisati ” tipa “bool ”. Ukoliko ovaj parametar ima vrijednost “true ”, funkcija treba da oslobodi prostor zauzet matricom koja joj je proslijeđena kao parametar, u suprotnom ne treba da radi ništa. Ovim se omogućava da možemo zadavati pozive poput IspisiMatricu(ZbirMatrica(a, b), 7, true );

tako da se oslobađanje memorije koju je zauzela pomoćna matrica koja predstavlja zbir matrica može obaviti bez korištenja pomoćne promjenljive (kao u programu “matrica struct.cpp ”). Pri tome, definirajte da parametar “treba brisati ” ima podrazumijevanu vrijednost “false ”, tako da ga ne treba navoditi ukoliko nam brisanje ne treba. Napisane funkcije testirajte u glavnom programu na primjeru matrica čije dimenzije i elemente unosi korisnik putem tastature. U glavnom programu predvidite hvatanje svih izuzetaka koji bi eventualno mogli nastupiti. Također, dobro pazite da nigdje ne dođe do curenja memorije, ni pod kakvim okolnostima (u suštini, to je i osnovni cilj zadatka). Napomena: Da, ovaj zadatak je već bio za zadaću u nekoliko prethodnih generacija. Naravno, možete ga “pođoniti”, ili Vam ga može uraditi neko drugi. Ali da znate, što bi rekao Balašević, neko to od gore vidi sve, i prije ili kasnije to će Vam se od glavu razbiti. Izuzetno je važno da barem ovaj zadatak zaista uradite sami (naravno, samostalno iste trebali uraditi i sve ostale zadatke, ali je izuzetno važno da baš ovaj zadatak ne prepišete ni .po koju cijenu). Ukoliko ne želite samostalno da uradite ovaj zadatak, radije ga nemojte ni predavati. 2. Zbog energetske krize, planiraju se restriktivna isključenja struje u pojedinim dijelovima grada. Grad je podijeljen u blokove, numerirane redom od 1 do N. Plan je da svaki M-ti blok počev od bloka 1 redom bude isključivan, nakon čega on ne dolazi u konkurenciju za ponovno isključivanje sve dok svaki blok ne bude barem jednom isključen. Pri tome se podrazumijeva da iza posljednjeg bloka ponovo dolazi blok sa rednim brojem 1, tako da se razbrajanje obavlja ciklično. Nakon što svi blokovi dođu na red, postupak se ponavlja ispočetka. Na primjer, ukoliko u gradu ima 10 blokova (sa rednim brojevima 1 – 10) i ukoliko je M= 4, redoslijed isključivanja je 1, 5, 9, 4, 10, 7, 6, 8, 3 i 2 (nacrtajte sliku), nakon čega ponovo započinje isti ciklus isključenja. Predložena strategija je očigledno pravična. Međutim, gospodin Hapo Kradibašić, ugledni predsjednik SPG-a (Stranke Pohlepnih Gulikoža), želi da kvart pod rednim brojem K u kojem se nalazi sjedište njegove stranke bude posljednji isključen, da ne bi došlo do remećenja priprema za predizbornu kampanju. Zbog toga on planira podmititi upravu Elektrodistribucije da odabere takav broj M da kvart pod rednim brojem K bude posljednji isključen. Vaš zadatak je da napravite program koji će gospodinu Kradibašiću pomoći da realizira svoju plemenitu zamisao. U programu treba implementirati dvije funkcije, “Razbrajanje ” i “OdabirKoraka ”. Funkcija “Razbrajanje ” prima kao parametre broj blokova N i korak razbrajanja M, a kao rezultat daje vektor koji redom sadrži redne blokove blokova koji se isključuju poredane u redoslijedu isključivanja. Na primjer, ukoliko je N= 10 i M= 4, ova

Page 115: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

funkcija vraća vektor čiji su elementi redom 1, 5, 9, 4, 10, 7, 6, 8, 3 i 2. Pri tome, funkcija treba biti zasnovana na povezanim listama čvorova, koje se često primjenjuju upravo za rješavanje problema srodnih opisanom problemu. Konkretno, prvo ćete definirati čvornu strukturu “Blok ” koja predstavlja jedan blok u gradu. Ona sadrži polje “redni broj ” tipa “ int ” i polje “sljedeci ” koje je po tipu pokazivač na strukturu tipa “Blok ”. Polje “ redni broj ” sadržavaće redni broj bloka, dok će polje “sljedeci ” pokazivati na sljedeći blok. Funkcija “Razbrajanje ” treba da kreira povezanu listu blokova (tj. čvorova tipa “Blok ”) čiji će redni brojevi biti postavljeni redom na vrijednosti od 1 do N, pri čemu će svaki blok pokazivati na blok sa narednim rednim brojem, osim posljednjeg bloka koji će pokazivati ponovo na prvi blok, čime se zapravo kreira krug blokoba (takve povezane liste u kojima posljednji čvor u listi pokazuje nazad na prvi čvor nazivaju se kružne ili cirkularne liste). Nakon što je formirana tražena lista, vrši se kretanje kroz listu, polazeći od prvog bloka, pri čemu se nakon svakih M napravljenih koraka odstranjuje onaj blok iz liste na kojoj se trenutno nalazimo i njegov redni broj smješta u izlazni vektor. Odstranjivanje se izvodi tako što se pokazivač “sljedeci ” bloka koji prethodi bloku na kojem se trenutno nalazimo preusmjerava tako da ne pokazuje više na blok na kojem se trenutno nalazimo nego na blok koji slijedi iza njega (čime se blok efektivno odstranjuje iz razmatranja) i prelazimo na sljedeći blok. Tom prilikom, pomoću operatora “delete ” potrebno je izbrisati čvor koji odgovara odstranjenom bloku, da ne zauzima više memoriju. Postupak se ponavlja dok se ne eliminira svih N blokova, nakon čega vraćamo vektor u kojem smo zapamtili redoslijed odstranjivanja blokova. Već je rečeno da program pored funkcije “Razbrajanje ”, treba implementirati i funkciju “OdabirKoraka ”. Ova funkcija kao parametre prima broj blokova N i redni broj odabranog bloka K, a rezultat daje korak razbrajanja M koji treba uzeti da bi posljednji isključeni blok bio upravo blok sa rednim brojem K. Ukoliko takvih koraka ima više, funkcija vraća najmanji mogući korak, a ukoliko slučajno takva vrijednost koraka ne postoji, funkcija kao rezultat vraća 0 (postavljaču zadatka nije poznato može li se ovo ikada desiti, ali predvidimo i ovo za svaki slučaj). Rad ove funkcije zasniva se na pozivanju funkcije “Razbrajanje ” za razne vrijednosti M sve dok se ne pronađe potrebni korak. Napisane funkcije demonstrirajte u testnom programu koji za zadane vrijednosti N i K ispisuje traženi korak razbrajanja koji gospodin Hapo Kradibašić treba saopćiti Elektrodistribuciji da bi postigao željeni cilj, Napomena: Za izradu programa nije dozvoljeno koristiti koncepte koji nisu obrađivani na predavanjima niti na kursu OR (recimo, tipove “list ”, “ set ” ili “ map”, razne bibliotečke funkcije koje nisu obrađivane, itd.). 3. Za potrebe neke aplikacije za dvodimenzionalnu kompjutersku grafiku, potrebno je razviti klasu “Tacka ” koja predstavlja tačku u ravni, sa sljedećim interfejsom: Tacka(); Tacka( double x, double y); void Postavi( double x, double y); void PostaviPolarno( double ro, double theta); double DajX() const ; double DajY() const ; double DajRo() const ; double DajTheta() const ; void PostaviX( double x); void PostaviY( double y); bool DaLiJeKoordinatniPocetak() const ; void Transliraj( double delta_x, double delta_y); void Rotiraj( double alpha, const Tacka &centar = Tacka()); friend bool DaLiSuIdenticne( const Tacka & t1, const Tacka & t2); friend double Rastojanje( const Tacka & t1, const Tacka & t2);

Konstruktor bez parametara kreira tačku u koordinatnom početku, dok konstruktor sa dva

Page 116: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

parametra kreira tačku na osnovu zadanih Dekartovih koordinata x i y. Istu stvar radi i metoda “Postavi ” (osim što omogućava naknadnu promjenu pozicije tačke. Metoda “PostaviPolarno ” radi sličnu stvar samo na osnovu polarnih koordinata ρ i θ (podsjetimo se da je veza između Deka rtovih i polarnih koordinata data formulama x =ρ cosθ, y =ρ sinθ odnosno ρ = √x2 + y2 , θ = atan2(x, y), gdje je “atan2” funkcija srodna funkciji “arkus tangens”, a podržana je u jezicima C/C++ baš pod tim imenom). Metode “DajX ”, “ DajY ”, “ DajRo ” i “DajTheta ” vraćaju kao rezultat odgovarajuće Dekartove odnosno polarne koordinate tačke, dok metode “PostaviX ” i “ PostaviY ” omogućavaju promjenu x odnosno y koordinate tačke (bez promjene preostale koordinate). Metoda “DaLiJeKoordinatniPocetak ” vraća logičku vrijednost “tačno” ili “netačno” u ovisnosti da li tačka na koju je metoda primijenjena predstavlja koordinatni početak ili ne. Metoda “Transliraj ” pomjera tačku za iznos ∆x u smjeru x-ose i iznos ∆y u smjeru y-ose, pri čemu se vrijednosti ∆x i ∆y navode kao parametri, dok metoda “Rotiraj ” rotira tačku za ugao α koji se zadaje kao prvi parametar (u smjeru suprotnom od kazaljke na satu) oko tačke koja se zadaje kao drugi parametar. Drugi parametar kao podrazumijevanu vrijednost ima tačku kreiranu u koordinatnom početku, čime je postignuto da se može zadati samo jedan parametar (pri čemu se tada rotacija vrši oko koordinatnog početka). Za one koji nisu dovoljno upućeni, recimo da se rotacijom tačke (x, y) oko tačke (xc, yc) za ugao α dobija tačka (x’, y’) gdje je x’ = xc + (x – xc) cosα– ( y – yc) sin α, y’ = yc + (x – xc) sinα+ (y – yc) cos α. Konačno, klasa podržava i dvije prijateljske funkcije. Funkcija “DaLiSuIdenticne ” vraća logičku vrijednost “tačno” ili “netačno” u ovisnosti da li su tačke koje su joj proslijeđene kao parametri identične ili ne, dok funkcija “Rastojanje ” vraća kao rezultat rastojanje između tačaka koje su joj proslijeđene kao parametri. Implementirajte klasu sa navedenim osobinama, pri čemu ćete uzeti da su atributi klase Dekartove koordinate tačke x i y. Napisanu klasu demonstrirajte u testnom programu koji traži da se tastature unese prirodan broj n, koji zatim treba dinamički alocirati niz od n tačaka (tj. objekata tipa “Tacka ”) koje treba inicijalizirati na osnovu podataka koji se unose sa tastature (podaci o svakoj tački se unose posebno). Nakon okončanja unosa, program treba prvo translirati a zatim rotirati sve unesene tačke u skladu sa podacima koji se unose sa tastature, te ispisati vrijednosti x, y, ρ i θ za sve unesene tačke nakon obavljenih transformacija. Na kraju, program treba ispitati da li među unesenim tačkama ima jednakih tačaka (rezultat ispitivanja treba prikazati na ekranu), te pronaći par tačaka koje se nalaze na najmanjem međusobnom rastojanju i ispisati koje su to tačke. NAPOMENA: U testnom programu se očigledno ne testiraju sve metode klase. To ne znači da one ostale metode koje nisu predviđene u testnom programu ne moraju raditi ispravno. 4. Pri razvoju neke hipotetičke aplikacije koja koristi klasu “Tacka ” razvijenu u prethodnom zadatku, uočeno je da će neki vitalni algoritmi u aplikaciji mnogo brže raditi ukoliko se koordinate tačke interno čuvaju u polarnom koordinatnom sistemu, te da je pogodnije kao atribute klase čuvati njene polarne koordinate ρ i θ. Implementirajte ponovo klasu “Tacka ” iz prethodnog zadatka koristeći ovako izmijenjen dizajn, ali tako da nova klasa zadrži isti interfejs, odnosno da korisnici klase (bar sa aspekta njene upotrebe) ne primijete da je njena implementacija izmijenjena. Posebno, testni program koji je razvijen u prethodnom zadatku treba da radi ispravno bez ikakvih izmjena sa novonapisanom verzijom klase “Tacka ”. NAPOMENA: Ukoliko prilikom rješavanja Zadatka 3. pametno napišete pojedine metode klase, nećete ih uopće morati mijenjati u novoj verziji klase (ideja je pisati metode tako da se što više oslanjaju na druge napisane metode). U suprotnom, možda ćete morati iznova napisati sve metode, što nije baš relaksirajuće. 5. Definirajte i implementirajte klasu “Trougao ” koja omogućava čuvanje podataka koji opisuju jedan trougao/trokut. Pri tome se trougao posmatra kao apstraktni geometrijski lik opisan isključivo dužinama svojih stranica, dok je njegov tačan položaj u ravni odnosno prostoru

Page 117: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

posve nebitan. Klasa treba da ima sljedeći interfejs: Trougao( double a); Trougao( double a, double b); Trougao( double a, double b, double c); void Postavi( double a); void Postavi( double a, double b); void Postavi( double a, double b, double c); static bool TestLegalnosti( double a, double b, double c); void OcitajStranice( double &a, double &b, double &c) const ; void OcitajUglove( double &alfa, double &beta, double &gama) const ; double DajObim() const ; double DajPovrsinu() const ; void Ispisi() const ; friend bool DaLiSuPodudarni( const Trougao & t1, const Trougao & t2); friend bool DaLiSuSlicni( const Trougao & t1, const Trougao & t2);

Konstruktor sa tri parametra kreira trougao čije su dužine stranica određene parametrima. Konstruktor sa dva parametra kreira pravougli trougao pri čemu parametri predstavljaju dužine kateta, dok konstruktor sa jednim parametrom kreira jednakostranični trougao pri čemu su dužine svih stranica jednake vrijednosti parametra.. Metode “Postavi ” (u tri varijante) načelno obavljaju isti zadatak kao i odgovarajući konstruktori, a omogućavaju naknadnu izmjenu podataka o trouglu. Svi konstruktori kao i metode “Postavi ” trebaju baciti izuzetak ukoliko nije moguće kreirati trougao sa zadanim parametrima. Degenerirani slučajevi u kojima se trougao reducira na duž (recimo trougao sa stranicama dužine 1, 2 i 3, ili dužine 2, 2 i 0) ili na tačku (recimo, trougao sa dužinama stranica 0, 0 i 0) također nisu dozvoljeni. Statička metoda “TestLegalnosti ” samo testira da li je moguće kreirati trougao sa stranicama koje su zadane kao parametri (bez bacanja izuzetaka) i vraća kao rezultat logičku vrijednost “tačno” ili “netačno” u zavisnosti da li je test uspio ili ne. Metoda “OcitajStranice ” smješta vrijednosti stranica u promjenljive koje su proslijeđene kao parametri, dok funkcija “OcitajUglove ” smješta vrijednosti odgovarajućih uglova/kutova izražene u radijanima u promjenljive koje su proslijeđene kao parametri (pri tome je alfa ugao naspram stranice a, itd.). Metode “DajObim ” i “ DajPovrsinu ” respektivno daju kao rezultat obim odnosno površinu trougla. Metoda “Ispisi ” ispisuje podatke o dužinama stranica, uglovima, obimu i površini trougla (stil ispisa oblikujte po volji). Konačno, prijateljske funkcije “DaLiSuPodudarni ” odnosno “DaLiSuSlicni ” testiraju da li su dva trougla koja im se prenose kao parametri podudarna odnosno slična i vraćaju kao rezultat logičku vrijednost “tačno” ili “netačno” ovisno od rezultata testiranja. Dva trougla su podudarna ukoliko imaju identične stranice (koje ne moraju biti u istom redoslijedu tako da su, na primjer, podudarni trouglovi sa stranicama 5, 12 i 10 odnosno 10, 5 i 12), a slična ukoliko su im stranice proporcionalne (vrijedi ista primjedba). Napisanu klasu demonstrirajte u testnom programu koji traži da se tastature unese prirodan broj n, koji zatim treba kreirati vektor koji sadrži n pokazivača na trouglove (tj. objekte tipa “Trougao ”). Nakon toga, sa tastature treba unijeti podatke za n trouglova (podaci o svakom trouglu se unose posebno), dinamički kreirati odgovarajuće trouglove (tj. objekte tipa “Trougao ”) inicijalizirane u skladu sa unijetim podacima i povezati ih sa odgovarajućim pokazivačima unutar vektora. Ukoliko korisnik zada vrijednosti stranica od kojih se ne može formirati trougao, treba ispisati poruku upozorenja i zatražiti novi unos podataka za isti trougao. Nakon okončanja unosa, program treba sortirati sve unesene trouglove u opadajući poredak po površini (tj. troguao sa većom površinom dolazi prije trougla sa manjom površinom) i ispisati podatke o svim trouglovima nakon obavljenog sortiranja. Za sortiranje obavezno koristiti bibliotečku funkciju “sort ” uz pogodno definiranu funkciju kriterija. Na kraju, program treba pronaći sve parove podudarnih i sličnih trouglova i ispisati koji su to trouglovi (ili obavijest da takvih parova nema).

Page 118: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

1.DOPUNA ZADATKA S PREDAVANJA(ima neko curenje memorije koje nisam imala kad ispravljati)

#include <iostream> #include <iomanip> using namespace std; template <typename TipElemenata> struct Matrica { int broj_redova, broj_kolona; TipElemenata **elementi; }; template <typename TipElemenata> void UnistiMatricu(Matrica<TipElemenata> mat) { if (mat.elementi == 0) return; for (int i = 0; i < mat.broj_redova; i++) delete[] mat.elementi[i]; delete[] mat.elementi; } template <typename TipElemenata> Matrica<TipElemenata> StvoriMatricu(int broj_redova, int broj_kolona) { Matrica<TipElemenata> mat; mat.broj_redova = broj_redova; mat.broj_kolona = broj_kolona; try { mat.elementi = new TipElemenata*[broj_redova];//dinamicki alocira pokazivace na redove for (int i = 0; i < broj_redova; i++) mat.elementi[i] = 0;//pokazivace postavlja na nulu for (int i = 0; i < broj_redova; i++) mat.elementi[i] = new TipElemenata[broj_kolona]; //dinamicki alocira cijeli red return mat; } catch (...) { UnistiMatricu(mat);//ako alokacija ne uspije throw; } }

Page 119: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

template <typename TipElemenata> void UnesiMatricu(char ime_matrice, Matrica<TipElemenata> &mat) { for (int i = 0; i < mat.broj_redova; i++)//standardni unos matrice for (int j = 0; j < mat.broj_kolona; j++) { cout << ime_matrice << "(" << i + 1 << "," << j + 1 << ") = "; cin >> mat.elementi[i][j]; } } template <typename TipElemenata> void IspisiMatricu(const Matrica<TipElemenata> &mat, int sirina_ispisa,bool treba_brisati=false) { for (int i = 0; i < mat.broj_redova; i++) { for (int j = 0; j < mat.broj_kolona; j++) cout << setw(sirina_ispisa) << mat.elementi[i][j]; cout << endl; } if (treba_brisati)UnistiMatricu(mat); } template <typename TipElemenata> Matrica<TipElemenata> ZbirMatrica(const Matrica<TipElemenata> &m1,const Matrica<TipElemenata> &m2) { if (m1.broj_redova != m2.broj_redova || m1.broj_kolona != m2.broj_kolona) throw "Matrice nemaju jednake dimenzije!\n"; Matrica<TipElemenata> m3(StvoriMatricu<TipElemenata>(m1.broj_redova,m1.broj_kolona));//matrica zbir for (int i = 0; i < m1.broj_redova; i++) for (int j = 0; j < m1.broj_kolona; j++) m3.elementi[i][j] = m1.elementi[i][j] + m2.elementi[i][j]; return m3; } template <typename TipElemenata> Matrica <TipElemenata>ProduktMatrica (const Matrica<TipElemenata> &m1,const Matrica<TipElemenata> &m2) {

Page 120: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

if (m1.broj_kolona!=m2.broj_redova) throw "Matrice nisu saglasne za mnozenje!"; Matrica<TipElemenata> m3(StvoriMatricu<TipElemenata>(m1.broj_redova,m2.broj_kolona)); for (int i=0;i<m1.broj_redova;i++) { for (int j=0;j<m2.broj_kolona;j++) { double suma(0); for (int k=0;k<m2.broj_redova;k++) { suma+=m1.elementi[i][k]*m2.elementi[k][j]; } m3.elementi[i][j]=suma; } } return m3; } template<typename TipElemenata> Matrica<TipElemenata> StepenMatrica(const Matrica<TipElemenata> matrica, int stepen) { Matrica<TipElemenata>stepenovana(StvoriMatricu<TipElemenata>(matrica.broj_redova,matrica.broj_kolona)); stepenovana=matrica; for (int i=0;i<(stepen-1);i++) { stepenovana=ProduktMatrica(stepenovana,matrica); } return stepenovana; } int main() { Matrica<double> a = {0, 0, 0}, b = {0, 0, 0}, c = {0, 0, 0},d = {0,0,0},e={0,0,0}; int m, n, g, h; cout << "Unesi broj redova i kolona za matrice A:\n"; cin >> m >> n; cout << "Unesi broj redova i kolona za matrice B:\n"; cin >> g >> h;

Page 121: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

try { a = StvoriMatricu<double>(m, n); b = StvoriMatricu<double>(g, h); cout << "Unesi matricu A:\n"; UnesiMatricu('A', a); cout << "Unesi matricu B:\n"; UnesiMatricu('B', b); cout << "Zbir ove dvije matrice je:\n"; IspisiMatricu(c = ZbirMatrica(a, b), 7); } catch (...) { cout << "Nema dovoljno memorije!\n"; } try { cout << "Proizvod ove dvije matrice je:\n"; IspisiMatricu(d = ProduktMatrica(a,b),7); } catch (...) { cout<<"Doslo je do greske pri alokaciji za produkt ili matrice nisu saglasne za mnozenje!"; } try { cout<<"Stepenovana matrica je->\n"; IspisiMatricu(e= StepenMatrica(a,3),7); } catch (...) { cout<<"Doslo je do greske pri alokaciji za stepen matrice ili matrice nisu saglasne za mnozenje!"; } UnistiMatricu(a); UnistiMatricu(b); UnistiMatricu(c); return 0;

Page 122: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

} 2.HAPO KRADIBAŠIĆ (najzanimljiviji zadatak :D, 100% tacan) #include <iostream> #include <vector> using namespace std; struct Blok { int redni_broj; Blok *sljedeci; }; vector<int> Razbrajanje (int N, int M) { vector<int> izlazni(N); //Kreiranje cirkularne liste Blok *Prvi (0),*Zadnji(0); for (int i=0;i<N;i++) { Blok *novi=new Blok;//dinamicki alociramo jedan blok (*novi).redni_broj=i+1; (*novi).sljedeci=0; if (Prvi!=0)(*Zadnji).sljedeci=novi;//povežemo čvorove else Prvi=novi;//samo za prvi čvor Zadnji=novi;//pok zadnji preusmjerimo na novokreirani blok (*Zadnji).sljedeci=Prvi;//zadnji povezujemo sa prvim } //Kreiranje vektora prema zadanom razbrajanju Blok *pok(Prvi); //Posto se prvi blok uvijek prvi gasi izlazni[0]=pok->redni_broj; Prvi=pok->sljedeci; Zadnji->sljedeci=Prvi; Blok *brisi(pok); //za ostale blokove for (int i=1;i<N;i++) { if (M==1) { pok=pok->sljedeci; delete brisi;brisi=0;

Page 123: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

izlazni[i]=pok->redni_broj; brisi=pok; continue; } for (int j=1;j<M;j++) pok=pok->sljedeci; delete brisi; brisi=0; izlazni[i]=pok->sljedeci->redni_broj; brisi=pok->sljedeci; pok->sljedeci=pok->sljedeci->sljedeci; } delete brisi; return izlazni; } int OdabirKoraka(int N, int K) { vector<int> razabir(N); for (int i=1;i<=N;i++) { razabir=Razbrajanje(N,i); for (int j=0;j<N;j++)cout<<endl<<razabir[j]; cout<<endl; if (razabir[N-1]==K) return i; } return 0; } int main() { cout << "Primili smo vasu molbu gospodine Hapo Kradibasicu,\npotrebno je samo da nam saopcite broj blokova i redni broj vase kuce."<<endl<<"Unesite broj blokova (N)->"; int N; cin >> N; cout <<"Unesite redni broj vaseg bloka koji treba biti posljednji ugasen->"; int K; cin >> K; int M; M=OdabirKoraka(N,K); if (M==0)

Page 124: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

{ cout << "Zao nam je gospodine Kradibasicu,\nne postoji korak razbrajanja da bismo udovoljili vasoj zelji,\nucinili smo sve sto je u nasoj moci."<<endl; } else { cout << "Za korak razbrajanja"<<M<<" vas blok ce zadnji biti ugasen"; } return 0; } 3.TACKA(ima greska u formuli za zakretanje ugla, ali nije previše važna za koncept shvatanja zadatka) #include <iostream> #include <cmath> using namespace std; const double Pi=4*atan(1.); class Tacka { double x,y; public: Tacka() { Postavi(0,0); } Tacka(double x, double y) { Postavi(x,y); } void Postavi(double x, double y) { Tacka::x=x; Tacka::y=y; } void PostaviPolarno(double ro, double theta) { x=ro*cos(theta); y=ro*sin(theta); } double DajX() const { return x; }

Page 125: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

double DajY() const { return y; } double DajRo() const { return sqrt(x*x+y*y); } double DajTheta() const { return atan2(y,x); } void PostaviX(double x) { Tacka::x=x; } void PostaviY(double y) { Tacka::y=y; } bool DaLiJeKoordinatniPocetak() const { if (x==0&&y==0) return true; return false; } void Transliraj(double delta_x, double delta_y) { x=x+delta_x; y=y+delta_y; } void Rotiraj(double alpha, const Tacka &centar = Tacka()) { Tacka pom; pom.x=centar.x+(x-centar.x)*cos(alpha)-(y-centar.y)*sin(alpha); pom.y=centar.y+(x-centar.x)*sin(alpha)+(y-centar.y)*cos(alpha); Postavi(pom.x,pom.y); } friend bool DaLiSuIdenticne(const Tacka &t1, const Tacka &t2);

Page 126: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

friend double Rastojanje(const Tacka &t1, const Tacka &t2); }; bool DaLiSuIdenticne(const Tacka &t1, const Tacka &t2) { if (t1.x==t2.x && t1.y==t2.y) return true; return false; } double Rastojanje(const Tacka &t1, const Tacka &t2) { return sqrt((t1.x-t2.x)*(t1.x-t2.x)+(t1.y-t2.y)*(t1.y-t2.y)); } int main() { cout << "Unesite vas broj tacaka(n)->" << endl; int n; cin>>n; Tacka *niz(0); try { niz=new Tacka[n]; } catch (...) { cout<<"Neuspjesna alokacija"; } double x(0),y(0); for (int i=0;i<n;i++) { cout<<i+1<<".tacka->"<<endl<<"x->"; cin>>x; cout<<"y->"; cin>>y; niz[i].Postavi(x,y); } for (int i=0;i<n;i++)cout<<niz[i].DajX()<<endl<<niz[i].DajY()<<endl; double deltaX(0),deltaY(0); cout<<"Sve tacke cemo translirati za"<<endl<<"deltaX->";

Page 127: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

cin>>deltaX; cout<<"deltaY->"; cin>>deltaY; for (int i=0;i<n;i++) { niz[i].Transliraj(deltaX,deltaY); } for (int i=0;i<n;i++)cout<<niz[i].DajX()<<endl<<niz[i].DajY()<<endl; double alfa(0); Tacka centarRotacije; cout<<"Sve tacke cemo rotirati za ugao alfa="; cin>>alfa; cout<<" oko centra rotacije->x->"; cin>>x; cout<<"y->"; cin>>y; centarRotacije.Postavi(x,y); for (int i=0;i<n;i++) { niz[i].Rotiraj(alfa*(Pi/180),centarRotacije); } for (int i=0;i<n;i++)cout<<i+1<<".tacka:"<<endl<<"x->"<<niz[i].DajX()<<endl<<"y->"<<niz[i].DajY()<<endl<<"ugao->"<<niz[i].DajTheta()*(180/Pi)<<endl<<"ro->"<<niz[i].DajRo()<<endl; bool ImaIstih(false); for (int i=0;i<n;i++) { for (int j=i;j<n;j++) { if (i!=j)ImaIstih=DaLiSuIdenticne(niz[i],niz[j]); } } if (ImaIstih)cout<<"Postoje identicne tacke u nizu."; else cout<<"Ne postoje identicne tacke u nizu."; double minimalno_rastojanje(Rastojanje(niz[0],niz[1])); cout<<minimalno_rastojanje; int pamtiPrvu(0),pamtiDrugu(1);

Page 128: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

for (int i=0;i<n;i++) { for (int j=i;j<n;j++) { if (i!=j) { if (Rastojanje(niz[i],niz[j])<minimalno_rastojanje) { minimalno_rastojanje=Rastojanje(niz[i],niz[j]); pamtiPrvu=i; pamtiDrugu=j; } } } } cout<<"Tacke na najmanjem rastojanju su:("<<niz[pamtiPrvu].DajX()<<","<<niz[pamtiPrvu].DajY()<<") i ("<<niz[pamtiDrugu].DajX()<<","<<niz[pamtiDrugu].DajY()<<")"; delete []niz; return 0; } 4.PREPRAVKA TACKE #include <iostream> #include <cmath> using namespace std; const double Pi=4*atan(1.); class Tacka { double ro,teta; public: Tacka() { Postavi(0,0); } Tacka(double x, double y) { Postavi(x,y); } void Postavi(double x, double y)

Page 129: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

{ ro=sqrt(x*x+y*y); teta=atan2(y,x); } void PostaviPolarno(double ro, double theta) { Tacka::ro=ro; teta=theta; } double DajX() const { return ro*cos(teta); } double DajY() const { return ro*sin(teta); } double DajRo() const { return ro; } double DajTheta() const { return teta; } void PostaviX(double x) { double y=ro*sin(teta); teta=atan2(y,x); ro=sqrt((ro*cos(teta))*(ro*cos(teta))+y*y); } void PostaviY(double y) { double x=ro*cos(teta); teta=atan2(y,x); ro=sqrt(x*x+(ro*sin(teta))*(ro*sin(teta))); } bool DaLiJeKoordinatniPocetak() const { if (ro*cos(teta)==0&&ro*sin(teta)==0) return true;

Page 130: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

return false; } void Transliraj(double delta_x, double delta_y) { double x=DajX(); double y=DajY(); x=x+delta_x; y=y+delta_y; Postavi(x,y); } void Rotiraj(double alpha, const Tacka &centar = Tacka()) { double x,y; x=DajX(); y=DajY(); x=centar.DajX()+(x-centar.DajX())*cos(alpha)-(y-centar.DajY())*sin(alpha); y=centar.DajY()+(x-centar.DajX())*sin(alpha)+(y-centar.DajY())*cos(alpha); Postavi(x,y); } friend bool DaLiSuIdenticne(const Tacka &t1, const Tacka &t2); friend double Rastojanje(const Tacka &t1, const Tacka &t2); }; bool DaLiSuIdenticne(const Tacka &t1, const Tacka &t2) { if (t1.DajX()==t2.DajX() && t1.DajY()==t2.DajY()) return true; return false; } double Rastojanje(const Tacka &t1, const Tacka &t2) { return sqrt((t1.DajX()-t2.DajX())*(t1.DajX()-t2.DajX())+(t1.DajY()-t2.DajY())*(t1.DajY()-t2.DajY())); } int main() { cout << "Unesite vas broj tacaka(n)->" << endl;

Page 131: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

int n; cin>>n; Tacka *niz; try { niz=new Tacka[n]; } catch (...) { cout<<"Neuspjesna alokacija"; } double x(0),y(0); for (int i=0;i<n;i++) { cout<<i+1<<".tacka->"<<endl<<"x->"; cin>>x; cout<<"y->"; cin>>y; niz[i].Postavi(x,y); } for (int i=0;i<n;i++)cout<<niz[i].DajX()<<endl<<niz[i].DajY()<<endl; double deltaX(0),deltaY(0); cout<<"Sve tacke cemo translirati za"<<endl<<"deltaX->"; cin>>deltaX; cout<<"deltaY->"; cin>>deltaY; for (int i=0;i<n;i++) { niz[i].Transliraj(deltaX,deltaY); } for (int i=0;i<n;i++)cout<<niz[i].DajX()<<endl<<niz[i].DajY()<<endl; double alfa(0); Tacka centarRotacije; cout<<"Sve tacke cemo rotirati za ugao alfa="; cin>>alfa; cout<<" oko centra rotacije->x->";

Page 132: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

cin>>x; cout<<"y->"; cin>>y; centarRotacije.Postavi(x,y); for (int i=0;i<n;i++) { niz[i].Rotiraj(alfa*(Pi/180),centarRotacije); } for (int i=0;i<n;i++)cout<<i+1<<".tacka:"<<endl<<"x->"<<niz[i].DajX()<<endl<<"y->"<<niz[i].DajY()<<endl<<"ugao->"<<niz[i].DajTheta()*(180/Pi)<<endl<<"ro->"<<niz[i].DajRo()<<endl; bool ImaIstih(false); for (int i=0;i<n;i++) { for (int j=i;j<n;j++) { if (i!=j)ImaIstih=DaLiSuIdenticne(niz[i],niz[j]); } } if (ImaIstih)cout<<"Postoje identicne tacke u nizu."; else cout<<"Ne postoje identicne tacke u nizu."; double minimalno_rastojanje(Rastojanje(niz[0],niz[1])); cout<<minimalno_rastojanje; int pamtiPrvu(0),pamtiDrugu(1); for (int i=0;i<n;i++) { for (int j=i;j<n;j++) { if (i!=j) { if (Rastojanje(niz[i],niz[j])<minimalno_rastojanje) { minimalno_rastojanje=Rastojanje(niz[i],niz[j]); pamtiPrvu=i; pamtiDrugu=j; } } } }

Page 133: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

cout<<"Tacke na najmanjem rastojanju su:("<<niz[pamtiPrvu].DajX()<<","<<niz[pamtiPrvu].DajY()<<") i ("<<niz[pamtiDrugu].DajX()<<","<<niz[pamtiDrugu].DajY()<<")"; delete[] niz; niz=0; return 0; } 5.TROUGAO #include <iostream> #include <cmath> #include <iomanip> #include <vector> #include <algorithm> using namespace std; const double PI=4*atan(1); class Trougao { double a,b,c; public: Trougao(double a) { Postavi(a); } Trougao(double a, double b) { Postavi(a,b); } Trougao(double a, double b, double c) { Postavi(a,b,c); } void Postavi(double a); void Postavi(double a, double b); void Postavi(double a, double b, double c); static bool TestLegalnosti(double a, double b, double c) { if ((a+b)<=c||(a+c)<=b||(b+c)<=a) return false;

Page 134: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

return true; } void OcitajStranice(double &a, double &b, double &c) const { a=Trougao::a; b=Trougao::b; c=Trougao::c; } void OcitajUglove(double &alfa, double &beta, double &gama) const { alfa=acos((b*b+c*c-a*a)/(2*b*c)); beta=acos((a*a+c*c-b*b)/(2*a*c)); gama=acos((a*a+b*b-c*c)/(2*a*b)); } double DajObim() const; double DajPovrsinu() const; void Ispisi() const; friend bool DaLiSuPodudarni(const Trougao &t1, const Trougao &t2); friend bool DaLiSuSlicni(const Trougao &t1, const Trougao &t2); }; void Trougao:: Postavi(double a) { bool postoji=TestLegalnosti(a,a,a); if (postoji) { Trougao::a=a; b=a; c=a; } else throw "Jednakostranicni trougao nije moguce formirati"; } void Trougao::Postavi(double a, double b) { bool postoji=TestLegalnosti(a,b,sqrt(a*a+b*b)); if (postoji) { Trougao::a=a; Trougao::b=b; c=sqrt(a*a+b*b); }

Page 135: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

else throw "Ovaj pravougli trougao nije moguce formirati"; } void Trougao::Postavi(double a, double b, double c) { bool postoji=TestLegalnosti(a,b,c); if (postoji) { Trougao::a=a; Trougao::b=b; Trougao::c=c; } else throw "Trougao nije moguce formirati."; } double Trougao:: DajObim() const { double O=a+b+c; return O; } double Trougao::DajPovrsinu() const { double H=(a+b+c)/2; return sqrt(H*(H-a)*(H-b)*(H-c)); } void Trougao ::Ispisi()const { double alfa, beta, gama; cout<<"Duzine stranica:a->"<<a<<setw(8)<<"b->"<<b<<setw(8)<<"c->"<<c<<setw(8)<<endl<<endl<<endl; OcitajUglove(alfa,beta,gama); cout<<"Uglovi trougla: alfa->"<<setprecision(4)<<alfa*(180/PI)<<setw(10)<<"beta->"<<setprecision(4)<<beta*(180/PI)<<setw(10)<<"gama->"<<setprecision(10)<<gama*(180/PI)<<setw(10)<<endl<<endl<<endl; cout<<"Povrsina trougla je->"<<setprecision(5)<<DajPovrsinu()<<endl<<endl; cout<<"Obim trougla je->"<<setprecision(5)<<DajObim()<<endl<<endl; } bool DaLiSuPodudarni(const Trougao &t1, const Trougao &t2)

Page 136: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

{ bool jesu(false); if (t1.a+t1.b+t1.c==t2.a+t2.b+t2.c&&t1.a*t1.b*t1.c==t2.a*t2.b*t2.c)jesu=true; return jesu; } bool DaLiSuSlicni(const Trougao &t1, const Trougao &t2) { bool jesu(false); if ((t1.a*t1.b*t1.c)/(t2.a*t2.b*t2.c)==pow((t1.a+t1.b+t1.c)/(t2.a+t2.b+t2.c), 3))jesu=true; return jesu; } bool Kriterij(Trougao *a, Trougao *b) { return (*a).DajPovrsinu()>(*b).DajPovrsinu(); } int main() { cout<<"Unesite vas broj trouglova->"; int n; cin>>n; vector<Trougao*> niz(n); double a(0),b(0),c(0); for (int i=0;i<n;i++) { cout<<"Unesite 'a' za "<<i+1<<". trougao->"; cin>>a; cout<<"Unesite 'b' za "<<i+1<<". trougao->"; cin>>b; cout<<"Unesite 'c' za "<<i+1<<". trougao->"; cin>>c; try { niz[i]=new Trougao(a,b,c); } catch (const char poruka[]) {

Page 137: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

cout<<poruka; cout<<"Unesite ponovo->"; i--; } } sort(niz.begin(),niz.end(),Kriterij); for (int i=0;i<n;i++) { cout<<i+1<<".trougao->"<<endl; (*niz[i]).Ispisi(); } bool Podudarni(false),Slicni(false); for (int i=0; i<n; i++) { for (int j=i+1; j<n; j++) { if (DaLiSuPodudarni(*niz[i], *niz[j])) { cout<<"Trouglovi "<< i+1 << " i " << j+1 <<" podudarni su!"<<endl; Podudarni=true; } if (DaLiSuSlicni(*niz[i], *niz[j])) { cout << "Trouglovi "<<i+1<< " i " <<j+1<<" slicni su!"<<endl; Slicni=true; } } } if (Podudarni==false)cout<<"Nema podudarnih trouglova."<<endl; if (Slicni==false)cout<<"Nema slicnih trouglova."<<endl; return 0; }

Page 138: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

Zadaća 4. Ova zadaća nosi ukupno 3,6 poena, pri čemu prvi i treći zadatak nose po 1,5 poen, a drugi zadatak nosi 0,6 poena. Sva tri zadatka se mogu uraditi na osnovu gradiva sa prvih 10 predavanja i pretpostavljenog predznanja iz predmeta “Osnove računarstva”. Rok za predaju ove zadaće je četvrtak, 24. V 2012. (do kraja dana) i ne može se produžiti. Zadaće se predaju putem Zamgera. 1. Implementirajte jednostavan program koji olakšava vođenje administrativnih poslova u nekoj biblioteci. Program se zasniva na dvije klase “Clan ” i “ Knjiga ”. Primjerci ovih klasa modeliraju respektivno članove (klijente) biblioteke i knjige u biblioteci. Klasa “Clan ” sadrži privatne atribute koji čuvaju informacije o evidencijskom (matičnom) broju člana, njegovom imenu i prezimenu, adresi, te broju telefona (svi ovi atributi su tipa “string ”, osim evidencijskog broja koji je cijeli broj). Interfejs klase sadrži konstruktor sa 5 parametara koji inicijalizira sve atribute na vrijednosti zadane parametrima, zatim trivijalne pristupne metode “DajEvidencijskiBroj ”, “ DajIme ”, “ DajPrezime ”, “ DajAdresu ” i “ DajTelefon ” koje prosto vraćaju vrijednosti odgovarajućih atributa, te metodu “Ispisi ” koja ispisuje podatke o članu na ekran (format ispisa izaberite po želji). Klasa “Knjiga ” sadrži privatne atribute koji čuvaju informacije o evidencijskom broju knjige, naslovu, imenu pisca, žanru i godini izdavanja, kao i informaciju o eventualnom zaduženju knjige. Evidencijski broj i godina izdavanja su cijeli brojevi, informacija o zaduženju čuva se kao pokazivač na člana koji je zadužio knjigu odnosno 0 ukoliko knjiga nije zadužena, dok su ostali atributi stringovnog tipa. Interfejs klase sadrži konstruktor sa 5 parametara koji inicijalizira sve atribute klase na vrijednosti zadane parametrima, osim informacije o zaduženju koja se postavlja tako da signalizira da knjiga nije zadužena. Pored konstruktora, interfejs klase sadrži trivijalne pristupne metode “DajEvidencijskiBroj ”, “ DajNaslov ”, “ DajAutora ”, “DajZanr ”, “ DajGodinuIzdanja ” i “ DajKodKogaJe ” koje vraćaju vrijednosti odgovarajućih atributa, te metode “ZaduziKnjigu ”, “ RazduziKnjigu ”, “ DaLiJeZaduzena ” i “ Ispisi ”. Metoda “ZaduziKnjigu ” vrši zaduživanje knjige, a parametar joj je referenca na člana koji zadužuje knjigu. Metoda “RazduziKnjigu ” nema parametara, a vrši razduživanje knjige. Metoda “DaLiJeZaduzena ” također nema parametara i prosto vraća logičku vrijednost “tačno” ili “netačno” u ovisnosti da li je knjiga zadužena ili ne, dok metoda “Ispisi ” vrši ispis podataka o knjizi na ekran (format ispisa izaberite po želji). Podaci o svakom članu odnosno svakoj knjizi čuvaju se u dinamički alociranim varijablama, kojima se pristupa pomoću dva vektora čiji su elementi pokazivači na članove (tj. na objekte tipa “Clan ”) odnosno pokazivači na knjige (tj. na objekte tipa “Knjiga ”). Broj elemenata ovih vektora nije unaprijed određen, nego raste po potrebi sa dodavanjem novih članova odnosno knjiga u evidenciju. Program treba da korisniku ponudi izbor jedne od sljedećih opcija, koje se izvršavaju u petlji sve dok korisnik ne odluči da završi rad: a) Registriranje novog člana. Izborom ove opcije, program treba pitati korisnika o ličnim podacima člana, nakon čega se kreira odgovarajući objekat tipa “Clan ” i upisuje u evidenciju. Program ne smije dozvoliti kreiranje člana čiji se evidencijski broj poklapa sa evidencijski brojem nekog od već postojećih članova. b) Pretraga članova. Izborom ove opcije, program treba pitati korisnika o evidencijskom broju, nakon čega pronalazi i ispisuje podatke o članu sa tim evidencijskim brojem, ili informaciju da takav član ne postoji. c) Izlistavanje članova. Izborom ove opcije, program treba da ispiše podatke o svim registriranim članovima, jedan za drugim. d) Registriranje nove knjige. Izborom ove opcije, program treba pitati korisnika o podacima o knjizi koja se registrira, nakon čega se kreira odgovarajući objekat tipa “Knjiga ” i upisuje u evidenciju. Program ne smije dozvoliti kreiranje člana čiji se evidencijski broj poklapa sa evidencijski brojem nekog od već postojećih članova. e) Zaduživnje knjige. Izborom ove opcije, program treba pitati korisnika o evidencijskom

Page 139: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

broju knjige, kao i o evidencijskom broju člana koji zadužuje knjigu, nakon čega se registrira da je knjiga zadužena kod navedenog člana. U slučaju da je neki od evidencijskih brojeva neispravan, ili ukoliko je knjiga već zadužena, treba prikazati odgovarajuću poruku o greški. f) Razduživanje knjige. Izborom ove opcije, program treba pitati korisnika o evidencijskom broju knjige, nakon čega registrira da knjiga nije više zadužena. U slučaju da je evidencijski broj neispravan, ili ukoliko knjiga nije zadužena, treba prikazati odgovarajuću poruku o greški. g) Pretraga knjiga. Izborom ove opcije, program treba pitati korisnika o evidencijskom broju, nakon čega pronalazi i ispisuje podatke o knjizi sa tim evidencijskim brojem, ili informaciju da takav član ne postoji. Ukoliko je knjiga zadužena, treba ispisati i osnovne podatke o članu kod koga se knjiga nalazi (evidencijski broj, ime i prezime). U suprotnom, treba ispisati da knjiga nije zadužena. h) Izlistavanje knjiga. Izborom ove opcije, program treba da ispiše podatke o svim registriranim članovima, jedan za drugim. i) Prikaz zaduženja. Izborom ove opcije, program treba pitati korisnika o evidencijskom broju člana, nakon čega ispisuje podatke o svim knjigama koje je zadužio navedeni član, ili informaciju da taj član nema zaduženja. U slučaju da je evidencijski broj neispravan, treba prikazati odgovarajuću poruku o greški. j) Kraj programa. Izborom ove opcije, program završava sa radom. 2. Izmijenite program “ucenici_obp.cpp ” priložen uz Predavanje 10 u skladu sa sljedećim zahtjevima: a) Atributi “ime ” i “ prezime ” u klasi “Ucenik ” sada će biti tipa “string ” umjesto niza znakova. Kao posljedica toga, konstruktor klase “Ucenik ” treba također da se promijeni, tim prije što više nije potrebno provjeravati da li je pređena maksimalna dozvoljena dužina imena odnosno prezimena. b) Ocjene se više neće čuvati u nizu cijelih brojeva, nego u vektoru cijelih brojeva (njegov kapacitet i dalje treba da bude “BrojPredmeta ” elemenata). c) U klasi “Razred ”, za evidenciju dinamički alociranih objekata tipa “Ucenik ” umjesto dinamički alociranog niza pokazivača treba koristiti vektor čiji su elementi pokazivači na objekte tipa “Ucenik ”. Pri tome, atributi koji čuvaju broj upisanih učenika i kapacitet razreda više neće biti potrebni. Zaista, broj upisanih učenika se može saznati testiranjem trenutne veličine vektora, dok kapacitet razreda više nije potrebno zadavati, s obzirom da vektor može u toku rada po volji povećavati svoju veličinu. Samim tim, konstruktoru više neće biti potreban parametar (zahvaljujući fleksibilnosti vektora, moći će se upisati onoliko učenika koliko želimo, bez potrebe da unaprijed specificiramo njihov maksimalan broj). Isto tako, metoda za evidentiranje novog učenika više ne treba provjeravati da li je dostignut maksimalan broj studenata, s obzirom da ograničenje na maksimalan broj učenika više ne postoji. Destruktor će i dalje biti potreban (da oslobodi sve dinamički alocirane objekte tipa “Ucenik ” nakon što objekat tipa “Razred ” prestane postojati). d) Potrebno je u klasu “Razred ” dodati konstruktor kopije i preklopljeni operator dodjele, s ciljem da se omogući bezbjedno kopiranje i međusobno dodjeljivanje objekata tipa “Razred ”, zasnovano na strategiji dubokog kopiranja. Naime, treba primijetiti da su dinamički alocirani objekti tipa “Ucenik ” u vlasništvu klase “Razred ”, iako nisu njen sastavni dio (razmislite dobro šta konstruktor kopije i preklopljeni operator dodjele tačno trebaju kopirati). Uvjerite se da uz ovakve modifikacije program i dalje radi ispravno. Posebno se trebate uvjeriti da konstruktor kopije i preklopljeni operator dodjele rade ispravno (za tu svrhu ćete morati ponešto dodati i u glavni program), i da nigdje ni pod kakvim okolnostima ne dolazi do curenja memorije.

Page 140: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

3. Za potrebe rekonstrukcija Željeznica Bosne i Hercegovine, potrebno je napraviti program koji će vršiti automatsku najavu polazaka preko ozvučenja na željezničkoj stanici. Program treba najavljivati sve vozove koji odlase sa stanice u toku dana, kao i eventualna kašnjenja u polascima. Za tu svrhu, u programu je potrebno razviti dvije klase nazvane “Polazak ” i “RedVoznje ”. Klasa “Polazak ” vodi evidenciju o jednom polasku, dok klasa “RedVoznje ” vodi evidenciju o svim polascima u toku dana. Klasa “Polazak ” ima sljedeći interfejs: Polazak(string odrediste, int broj_voza, int broj_perona, bool brzi_voz, int sat_polaska, int minute_polaska, int trajanje_voznje); void PostaviKasnjenje( int kasnjenje); bool DaLiKasni() const ; int DajTrajanjeVoznje() const ; void OcekivanoVrijemePolaska( int &sati, int &minute) const ; void OcekivanoVrijemeDolaska( int &sati, int &minute) const ; void Ispisi() const ;

Objekti tipa “Polazak ” čuvaju u sebi informaciju o nazivu odredišta, broju voza (cijeli broj sa maksimalno 5 cifara), broju perona (cijeli broj u opsegu od 1 do 6), informaciju o tome da li je voz brzi voz ili ne, vremenu polaska (sati i minute), trajanju vožnje u minutama, kao i informaciju o eventualnom kašnjenju (također u minutama). Konstruktor inicijalizira objekat u skladu sa vrijednostima zadanim parametrima konstruktora, osim informacije o eventualnom kašnjenju, koja se automatski inicijalizira na 0. Konstruktor treba da baci izuzetak ukoliko bilo koji od parametara ima besmislene vrijednosti. Metoda “PostaviKasnjenje ” postavlja informaciju o eventualnom kašnjenju na vrijednost zadanu parametrom, dok metoda “DaLiKasni ” omogućava da se sazna da li odgovarajuća vožnja kasni ili ne (metoda vraća logičku vrijednost “true ” u slučaju kašnjenja, a logičku vrijednost “false ” u suprotnom slučaju). Metoda “DajTrajanje ” daje kao rezultat trajanje vožnje u minutama, dok metode “OcekivanoVrijemePolaska ” i “ OcekivanoVrijemeDolaska ” omogućavaju da se sazna očekivano vrijeme polaska odnosno dolaska kada se uračuna iznos kašnjenja u odnosu na predviđeno vrijeme polaska/dolaska. Obje metode treba da smjeste sate i minute očekivanog vremena polaska/dolaska u dva cjelobrojna parametra koji joj se prosljeđuju. Konačno, metoda “ Ispisi ” treba da podrži ispis objekata tipa “Polazak ” na ekran. U slučaju da se radi o polasku bez kašnjenja, ispis bi trebao da izgleda poput sljedećeg: Lokalni voz broj 3423, odredište Zenica, polazi sa perona 2 u 15:40, a na odredište stiže u 17:10. Putnicima i voznom osoblju želimo ugodno putovanje. U stvarnom sistemu, ovaj tekst bi se trebao proslijediti sklopu za sintezu govora koji bi emitirao govornu informaciju preko ozvučenja, ali za potrebe ovog zadatka zadovoljićemo se prostim ispisom na ekran. U slučaju da se radi o polasku koji kasni, ispis bi trebao da izgleda poput sljedećeg: Brzi voz broj 358, odrediste Ploče, sa predviđenim vremenom polaska u 6:40, kasni oko 35 minuta, te će poći oko 7.15. Očekuje se da voz stigne na odredište oko 10:30. Izvinjavamo se putnicima zbog eventualnih neugodnosti. Klasa “RedVoznje ” ima sljedeći interfejs: explicit RedVoznje ( int max_broj_polazaka); ~ RedVoznje (); RedVoznje ( const RedVoznje &red_voznje); RedVoznje &operator =( const RedVoznje &red_voznje); void RegistrirajPolazak(string odrediste, int broj_voza, bool brzi_voz, int broj_perona, int sat_polaska, int minute_polaska, int trajanje_voznje); void RegistrirajPolazak(Polazak *polazak); int DajBrojPolazaka() const ; int DajBrojPolazakaKojiKasne() const ; int DajProsjecnoTrajanjeVoznji() const ; Polazak &DajPrviPolazak() const ; Polazak &DajPosljednjiPolazak() const ;

Page 141: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

void IsprazniKolekciju(); void Ispisi( int sati, int minute) const ;

Podaci o polascima se čuvaju u dinamički alociranim objektima tipa “Polazak ”, kojima se opet pristupa preko dinamički alociranog niza pokazivača na takve objekte. Alokacija tog niza pokazivača vrši se iz konstruktora. Parametar konstruktora predstavlja maksimalan broj polazaka koji se mogu registrirati. Destruktor oslobađa svu memoriju koja je zauzeta tokom života objekta, dok konstruktor kopije i preklopljeni operator dodjele omogućavaju bezbjedno kopiranje i međusobno dodjeljivanje objekata tipa “RedVoznje ” korištenjem strategije dubokog kopiranja. Metoda “RegistrirajPolazak ” podržana je u dvije verzije. Prva verzija kreira novi polazak u skladu sa parametrima (koji su identični kao kod konstruktora klase “Polazak ”) i registrira ga u kolekciji, dok druga verzija prosto kao parametar prihvata pokazivač na objekat tipa “Polazak ” (za koji pretpostavljamo da je već na neki način kreiran) i registira ga u kolekciji. U oba slučaja, treba baciti izuzetak u slučaju da je dostignut maksimalan broj polazaka koji se mogu registrirati u kolekciji. Metode “DajBrojPolazaka ”, “DajBrojPolazakaKojiKasne ” i “ DajProsjecnoTrajanjeVoznje ” daju respektivno ukupan broj registriranih polazaka, broj polazaka koji kasne, te prosječno trajanje svih registriranih vožnji u minutama. Metode “DajPrviPolazak ” i “ DajPosljednjiPolazak ” daju kao rezultat prvi i posljednji polazak (tj. odgovarajući objekat tipa “Polazak ”) u toku dana (uključujući i eventualna kašnjenja). Obje metode vraćaju kao rezultat referencu da se izbjegne nepotrebno kopiranje objekata. Metoda “IsprazniKolekciju ” uklanja sve registrirane polaske, tako da je nakon poziva ove metode kolekcija u identičnom stanju kakva je bila neposredno nakon kreiranja. Konačno, metoda “Ispisi ” ispisuje informacije o svim polascima, počev od zadanog vremena do kraja dana, sortiranu po očekivanim vremenima polazaka (za sortiranje iskoristite funkciju “sort ”, uz pogodno definiranu funkciju kriterija koja treba biti privatna statička funkcija članica klase). Ispis pojedinačnih polazaka vrši se prostim pozivom metode “Ispisi ” nad objektima tipa “Polazak ” pohranjenim u kolekciji. Sve metode implementirajte izvan deklaracije klase, osim trivijalnih metoda koje trebate implementirati direktno unutar deklaracije klase. Obavezno napišite i testni program u kojem ćete testirati sve elemente napisanih klasa. Posebno se trebate uvjeriti da konstruktor kopije i preklopljeni operator dodjele rade ispravno, kao i da ni u kom slučaju ne dolazi do curenja memorije. 1.BIBLIOTEKA

#include <iostream> #include <string> #include <vector> using namespace std; class Clan { int mat_broj_clana; string ime; string prezime; string adresa; string br_telefona; public: //Clan::Constructor

Page 142: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

Clan(int mat_broj_clana,string ime, string prezime, string adresa, string br_telefona):mat_broj_clana(mat_broj_clana),ime(ime),prezime(prezime),adresa(adresa),br_telefona(br_telefona){} //Clan::Methods int DajEvidencijskiBroj()const { return mat_broj_clana; } string DajIme()const { return ime; } string DajPrezime()const { return prezime; } string DajAdresu()const { return adresa; } string DajTelefon()const { return br_telefona; } void Ispisi()const { cout<<"Ime clana->"<<ime<<endl; cout<<"Prezime clana->"<<prezime<<endl; cout<<"Adresa stanovanja clana->"<<adresa<<endl; cout<<"Kontakt telefon clana->"<<br_telefona<<endl<<endl; } }; class Knjiga { int Evidencijski_knjige; string Naslov; string ImePisca; string Zanr; int GodinaIzdavanja; Clan *Onaj_koji_je_zaduzio_knjigu; public: //Knjiga::Constructor

Page 143: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

Knjiga(int Evidencijski_knjige, string Naslov, string ImePisca, string Zanr, int GodinaIzdavanja):Evidencijski_knjige(Evidencijski_knjige),Naslov(Naslov),ImePisca(ImePisca),Zanr(Zanr),GodinaIzdavanja(GodinaIzdavanja) { Onaj_koji_je_zaduzio_knjigu=0; } //Knjiga::Methods //Trivijalne metode int DajEvidencijskiBroj()const { return Evidencijski_knjige; } string DajNaslov()const { return Naslov; } string DajAutora()const { return ImePisca; } string DajZanr()const { return Zanr; } int DajGodinuIzdanja()const { return GodinaIzdavanja; } Clan* DajKodKogaJe()const { return Onaj_koji_je_zaduzio_knjigu; } //ostale void ZaduziKnjigu(Clan &OnajKojiZaduzuje) { Onaj_koji_je_zaduzio_knjigu=&OnajKojiZaduzuje; } void RazduziKnjigu() { Onaj_koji_je_zaduzio_knjigu=0; } bool DaLiJeZaduzena()

Page 144: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

{ if (Onaj_koji_je_zaduzio_knjigu!=0)return true; return false; } void Ispisi()const { cout<<"Evidencijski broj knjige->"<<Evidencijski_knjige<<endl; cout<<"Naslov knjige->"<<Naslov<<endl; cout<<"Ime i prezime autora knjige->"<<ImePisca<<endl; cout<<"Zanr knige->"<<Zanr<<endl; cout<<"Godina izdavanja knjige->"<<GodinaIzdavanja<<endl; } }; int main() { /*Clan unika(2006,"tajma", "kovacevic", "mostar", "062-090-006"); unika.Ispisi(); Knjiga neka(111,"bajke","grim","bajke",1999); cout<<neka.DajAutora(); cout<<neka.DajKodKogaJe(); neka.ZaduziKnjigu(unika); cout<<neka.DajKodKogaJe()->DajIme(); cout<<neka.DaLiJeZaduzena(); neka.Ispisi();*/ vector<Clan*>clanovi; vector<Knjiga*>knjige; //Naredbe koje se izvrsavaju u petlji sve dok korisnik ne odluci da zavrsi rad. for (;;) { int n; cout<<"Odaberite jednu od ponudjenih opcija:\n 1-Registriranje novog clana\n 2-Pretraga clanova \n 3-Izlistavanje clanova\n 4-Registriranje nove knjige\n 5-Zaduzivanje knjige\n 6-Razduzivanje knige\n 7-Pretraga knjiga\n 8-Izlistavanje knjiga\n 9-Prikaz zaduzenja\n 10-Kraj rada"; cout<<endl; cin>>n; cin.ignore(1000,'\n'); if (n==1)//registriranje novog clana { string ime, prezime, br_telefona,adresa; int mat_broj_clana;

Page 145: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

cout<<"Unesite ime clana kojeg registrirate->"; getline(cin,ime); cout<<"Unesite prezime clana kojeg registrirate->"; getline(cin,prezime); cout<<"Unesite adresu clana kojeg registrirate->"; getline(cin,adresa); cout<<"Unesite broj telefona clana kojeg registrirate->"; getline(cin,br_telefona); cout<<"Unesite evidencijski broj clana kojeg registrirate->"; cin>>mat_broj_clana; bool postoji(false); for (int i=0;i<clanovi.size();i++) { if (mat_broj_clana==clanovi[i]->DajEvidencijskiBroj()) { postoji=true; break; } } if (postoji) { cout<<"Vec postoji clan sa unesenim evidencijskim brojem!"<<endl; } else { clanovi.resize(clanovi.size()+1); try { clanovi[clanovi.size()-1]=new Clan(mat_broj_clana,ime,prezime,adresa,br_telefona); } catch (...) { cout<<"Alokacija clana nije uspjela!"<<endl; delete clanovi[clanovi.size()-1]; } } }//od n==1 if (n==2)

Page 146: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

{ int ev_broj; cout<<"Unesite evidencijski broj clana kojeg trazite->"<<endl; cin>>ev_broj; bool ne_postoji(true); for (int i=0;i<clanovi.size();i++) { if (ev_broj==clanovi[i]->DajEvidencijskiBroj()) { clanovi[i]->Ispisi(); ne_postoji=false; break; } } if (ne_postoji)cout<<"Ne postoji clan sa unesenim evidencijskim brojem!"<<endl; }//od n==2 if (n==3) { for (int i=0;i<clanovi.size();i++) clanovi[i]->Ispisi(); }//od n==3 //registriranje nove knjige if (n==4) { int Evidencijski_knjige; string Naslov,ImePisca,Zanr; int GodinaIzdavanja; cout<<"Unesite naslov knjige koju registrirate->"<<endl; getline(cin,Naslov); cout<<"Unesite ime autora knige koju registrirate->"<<endl; getline(cin,ImePisca); cout<<"Unesite zanr knjige koju registrirate->"<<endl; getline(cin, Zanr); cout<<"Unesite godinu izdavanja knjige koju registrirate->"<<endl; cin>>GodinaIzdavanja; cout<<"Unesite evidencijski broj knjige koju registrirate->"<<endl; cin>>Evidencijski_knjige; bool postoji(false); for (int i=0;i<knjige.size();i++)

Page 147: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

{ if (Evidencijski_knjige==knjige[i]->DajEvidencijskiBroj()) { postoji=true; break; } } if (postoji) { cout<<"Vec postoji knjiga sa unesenim evidencijskim brojem!"<<endl; } else { knjige.resize(knjige.size()+1); try { knjige[knjige.size()-1]=new Knjiga(Evidencijski_knjige,Naslov,ImePisca,Zanr,GodinaIzdavanja); } catch (...) { cout<<"Alokacija knjige nije uspjela!"; delete knjige[knjige.size()-1]; } } }//od n==4 //zaduzivanje knjige if (n==5) { int ev_clana, ev_knjige; cout<<"Unesite evidencijski broj clana koji zaduzuje knjigu->"<<endl; cin>>ev_clana; cout<<"Unesite evidencijski broj knjige koju clan zeli zaduziti->"<<endl; cin>>ev_knjige; bool ne_postoji_clan(true); int sacuvaj_clana; for (int i=0;i<clanovi.size();i++) { if (ev_clana==clanovi[i]->DajEvidencijskiBroj()) { ne_postoji_clan=false; sacuvaj_clana=i;

Page 148: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

break; } } if (ne_postoji_clan)cout<<"Unijeli ste pogresan evidencijski broj clana, clan sa unesenim evidencijskim brojem ne postoji!"; else { bool ne_postoji_knjiga(true); int sacuvaj_knjigu; for (int i=0;i<knjige.size();i++) { if (ev_knjige==knjige[i]->DajEvidencijskiBroj()) { ne_postoji_knjiga=false; sacuvaj_knjigu=i; break; } } if (ne_postoji_knjiga)cout<<"Ne postoji knjiga sa unesenim evidencijskim brojem!"<<endl; else { if (knjige[sacuvaj_knjigu]->DaLiJeZaduzena())cout<<"Knjiga sa unesenim evidencijskim brojem je vec zaduzena!"<<endl; else { knjige[sacuvaj_knjigu]->ZaduziKnjigu(*clanovi[sacuvaj_clana]); } } } }//od n==5 //razduzivanje knjige if (n==6) { int ev_knjige; cout<<"Unesite evidencijski broj knjige koju razduzujete->"<<endl; cin>>ev_knjige; bool ne_postoji(true); for (int i=0;i<knjige.size();i++) { if (ev_knjige==knjige[i]->DajEvidencijskiBroj()) {

Page 149: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

knjige[i]->RazduziKnjigu(); ne_postoji=false; break; } } if (ne_postoji)cout<<"Ne postoji knjiga s tim evidencijskim brojem."<<endl; }//od n==6 //pretraga knjiga if (n==7) { int ev_knjige; cout<<"Unesite evidencijski broj knjige->"; cin>>ev_knjige; bool ne_postoji(true); for (int i=0;i<knjige.size();i++) { if (ev_knjige==knjige[i]->DajEvidencijskiBroj()) { ne_postoji=false; knjige[i]->Ispisi(); if (knjige[i]->DaLiJeZaduzena()) { cout<<"Clan kod kog je zaduzena knjiga(evidencijski broj,ime, prezime):\n"<<knjige[i]->DajKodKogaJe()->DajEvidencijskiBroj()<<" "<<knjige[i]->DajKodKogaJe()->DajIme()<<" "<<knjige[i]->DajKodKogaJe()->DajPrezime()<<endl; } else { cout<<"Knjiga nije zaduzena!"<<endl; } break; } } if (ne_postoji)cout<<"Ne postoji knjiga sa unesenim evidencijskim brojem!"<<endl; }//od n==7 if (n==8) { for (int i=0;i<knjige.size();i++) knjige[i]->Ispisi(); }//od n==8 //prikaz zaduzenja

Page 150: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

if (n==9) { int ev_broj; cout<<"Unesite evidencijski broj clana za koji zelite vidjeti zaduzene knjige->"; cin>>ev_broj; bool ne_postoji(true); for (int i=0;i<clanovi.size();i++) { if (ev_broj==clanovi[i]->DajEvidencijskiBroj()) { ne_postoji=false; for (int j=0;j<knjige.size();j++) { bool nema_zaduzenja(true); if ( knjige[j]->DajKodKogaJe()==clanovi[i]) { nema_zaduzenja=false; cout<<endl<<"Zaduzena knjiga->"<<endl; knjige[j]->Ispisi(); } if (nema_zaduzenja)cout<<"Ovaj clan nema zaduzenih knjiga!"<<endl; } } } if (ne_postoji)cout<<"Evidencijski broj clana koji ste unijeli ne postoji!"<<endl; }//od n==9 if (n==10) break; }//od glavne for petlje for(int i=0;i<clanovi.size();i++)delete clanovi[i]; for(int i=0;i<knjige.size();i++)delete knjige[i]; return 0; }

Page 151: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

2. ucenici_obp.cpp

#include <iostream> #include <iomanip> #include <algorithm> #include <string> #include <vector> using namespace std; class Datum { int dan, mjesec, godina; public: Datum(int d, int m, int g); void Unesi(); void Ispisi() const { cout << dan << "." << mjesec << "." << godina; } }; class Ucenik { static const int BrojPredmeta=2; // Pri testiranju smanjite ovaj broj string ime, prezime; Datum datum_rodjenja; vector<int>ocjene; double prosjek; bool prosao; public: Ucenik(string ime, string prezime, int d, int m, int g); void PostaviOcjenu(int predmet, int ocjena); static int DajBrojPredmeta() { return BrojPredmeta; } double DajProsjek() const { return prosjek; } bool DaLiJeProsao() const { return prosao; }

Page 152: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

void Ispisi() const; }; class Razred { vector<Ucenik*>ucenici; static bool BoljiProsjek(const Ucenik *u1, const Ucenik *u2) { return u1->DajProsjek() > u2->DajProsjek(); } public: //constructor explicit Razred():ucenici(0){}; //konstruktor kopije Razred(const Razred &r) { ucenici.resize(r.ucenici.size()); for (int i=0;i<ucenici.size();i++) ucenici[i]=new Ucenik(*r.ucenici[i]); } //destructor ~Razred(); //Operator dodjele Razred &operator=(const Razred &r) { if (ucenici.size()!=r.ucenici.size()) { for (int i=0;i<ucenici.size();i++) delete ucenici[i]; ucenici.resize(r.ucenici.size()); } for (int i=0;i<ucenici.size();i++) ucenici[i]=new Ucenik(*r.ucenici[i]); return *this; } //methods void EvidentirajUcenika(Ucenik *ucenik); void UnesiNovogUcenika(); void IspisiIzvjestaj() const; void SortirajUcenike() {

Page 153: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

sort(ucenici.begin(), ucenici.end(), BoljiProsjek); } }; int main() { try { int broj_ucenika; cout << "Koliko ima ucenika: "; cin >> broj_ucenika; if (!cin) throw 0; // Ovdje je nebitno �ta bacamo... Razred razred; for (int i = 1; i <= broj_ucenika; i++) { cout << "Unesi podatke za " << i << " ucenika:\n"; razred.UnesiNovogUcenika(); } razred.SortirajUcenike(); razred.IspisiIzvjestaj(); Razred novi(razred); novi.IspisiIzvjestaj(); } catch (...) { cout << "Problemi sa memorijom!\n"; } return 0; } //konstruktor klase datum Datum::Datum(int d, int m, int g) { int broj_dana[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if (g % 4 == 0 && g % 100 != 0 || g % 400 == 0) broj_dana[1]++; if (g < 1 || d < 1 || m < 1 || m > 12 || d > broj_dana[m - 1]) throw "Neispravan datum!"; dan = d; mjesec = m; godina = g; } //konstruktor klase ucenik Ucenik::Ucenik(string ime, string prezime, int d, int m, int g) :ime(ime),prezime(prezime), datum_rodjenja(d, m, g), prosjek(1), prosao(false)

Page 154: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

{ for (int i = 0; i <ocjene.size(); i++) ocjene[i] = 1; } void Ucenik::PostaviOcjenu(int predmet, int ocjena) { if (ocjena < 1 || ocjena > 5) throw "Pogresna ocjena!"; if (predmet < 1 || predmet > BrojPredmeta) throw "Pogresan broj predmeta!"; ocjene.resize(BrojPredmeta); ocjene[predmet - 1] = ocjena; prosjek = 1; prosao = false; double suma_ocjena(0); for (int i = 0; i < BrojPredmeta; i++) { if (ocjene[i] == 1) return; suma_ocjena += ocjene[i]; } prosjek = suma_ocjena / BrojPredmeta; prosao = true; } void Ucenik::Ispisi() const { cout << "Ucenik " << ime << " " << prezime << " rodjen "; datum_rodjenja.Ispisi(); if (DaLiJeProsao()) cout << " ima prosjek " << setprecision(3) << DajProsjek() << endl; else cout << " mora ponavljati razred\n"; } //destruktor Razred::~Razred() { for (int i = 0; i < ucenici.size(); i++) delete ucenici[i]; } void Razred::EvidentirajUcenika(Ucenik *ucenik) { ucenici.resize(ucenici.size()+1); ucenici[ucenici.size()-1] = ucenik; }

Page 155: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

void Razred::UnesiNovogUcenika() { bool pogresan_unos(true); while (pogresan_unos) {Ucenik *ucenik=0; try { string ime, prezime; int d, m, g; char znak1, znak2; cin.ignore(1000,'\n'); cout << " Ime: "; getline(cin,ime); cout << " Prezime: "; getline(cin,prezime); cout << " Datum rodjenja (D/M/G): "; cin >> d >> znak1 >> m >> znak2 >> g; if (!cin || znak1 != '/' || znak2 != '/') throw "Pogresan datum!"; ucenik = new Ucenik(ime, prezime, d, m, g); for (int pr = 1; pr <= Ucenik::DajBrojPredmeta(); pr++) { int ocjena; cout << " Ocjena iz " << pr << ". predmeta: "; cin >> ocjena; if (!cin) throw "Pogresna ocjena!"; ucenik->PostaviOcjenu(pr, ocjena); } EvidentirajUcenika(ucenik); pogresan_unos = false; } catch (const char greska[]) { cout << "Greska: " << greska << "\nMolimo, ponovite unos!\n"; cin.clear(); cin.ignore(10000, '\n'); delete ucenik; } } } void Razred::IspisiIzvjestaj() const { cout << endl; for (int i = 0; i < ucenici.size(); i++)

Page 156: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

ucenici[i]->Ispisi(); } 3.ZELJEZNICE BIH #include <iostream> #include <string> using namespace std; class Polazak { string odrediste; int broj_voza;//cijeli broj sa maksimalno 5 cifara int broj_perona;//cijel broj u opsegu od 1 do 6 bool brzi_voz; int sat_polaska; int minute_polaska; int kasnjenje;//u minutama int trajanje_voznje;//u minutama public: //Constructor Polazak(string odrediste, int broj_voza, int broj_perona,bool brzi_voz, int sat_polaska, int minute_polaska,int trajanje_voznje); //Methods void PostaviKasnjenje(int kasnjenje) { Polazak::kasnjenje=kasnjenje; } bool DaLiKasni() const { if (kasnjenje!=0) return true; return false; } int DajTrajanjeVoznje() const { return trajanje_voznje; } void OcekivanoVrijemePolaska(int &sati, int &minute) const; void OcekivanoVrijemeDolaska(int &sati, int &minute) const; void Ispisi() const; };

Page 157: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

void Polazak:: OcekivanoVrijemePolaska(int &sati, int &minute) const { if ((minute_polaska+kasnjenje)>60) { minute=(minute_polaska+kasnjenje)%60; sati=sat_polaska+((minute_polaska+kasnjenje)/60); } else { minute=minute_polaska+kasnjenje; sati=sat_polaska; } if (sati>24) while (sati>24)sati-=24; } void Polazak:: OcekivanoVrijemeDolaska(int &sati, int &minute) const { if (minute_polaska+trajanje_voznje+kasnjenje>60) { sati=sat_polaska+((minute_polaska+trajanje_voznje+kasnjenje)/60); minute=(minute_polaska+trajanje_voznje+kasnjenje)%60; } else { sati=sat_polaska; minute=minute_polaska+kasnjenje+trajanje_voznje; } } void Polazak:: Ispisi() const { if (kasnjenje==0) { if (brzi_voz==false) cout<<"Lokalni voz broj "<<broj_voza<<", odrediste "<<odrediste<<", polazi sa perona "<<broj_perona<<" u "<<sat_polaska<<":"<< minute_polaska<<",a na odrediste stize u"<<sat_polaska+((minute_polaska+trajanje_voznje)/60)<<":"<<(minute_polaska+trajanje_voznje)%60 <<". Putnicima i voznom osoblju zelimo ugodno putovanje."<<endl;

Page 158: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

if (brzi_voz) cout<<"Brzi voz broj "<<broj_voza<<", odrediste "<<odrediste<<", polazi sa perona "<<broj_perona<<" u "<<sat_polaska<<":"<< minute_polaska<<",a na odrediste stize u"<<sat_polaska+((minute_polaska+trajanje_voznje)/60)<<":"<<(minute_polaska+trajanje_voznje)%60 <<". Putnicima i voznom osoblju zelimo ugodno putovanje."<<endl; } /*Brzi voz broj 358, odrediste Ploče, sa predviđenim vremenom polaska u 6:40, kasni oko 35 minuta, te će poći oko 7.15. Očekuje se da voz stigne na odredište oko 10:30. Izvinjavamo se putnicima zbog eventualnih neugodnosti.*/ if (kasnjenje!=0) { if (brzi_voz==false) cout<<"Lokalni voz broj "<<broj_voza<<",odrediste "<<odrediste<<", sa predvidjenim vremenom polaska u "<<sat_polaska<<":"<<minute_polaska<<", kasni oko "<< kasnjenje<<" minuta, te ce poci oko"<<sat_polaska+((minute_polaska+kasnjenje)/60)<<":"<<(minute_polaska+kasnjenje)%60<<".Ocekuje se da voz stigne na odrediste oko "<< sat_polaska+((minute_polaska+trajanje_voznje+kasnjenje)/60)<<":"<<(minute_polaska+trajanje_voznje+kasnjenje)%60<<".Izvinjavamo se putnicima zbog eventualnih neugodnosti."<<endl; if (brzi_voz) cout<<"Brzi voz broj "<<broj_voza<<",odrediste "<<odrediste<<", sa predvidjenim vremenom polaska u "<<sat_polaska<<":"<<minute_polaska<<", kasni oko "<< kasnjenje<<" minuta, te ce poci oko"<<sat_polaska+((minute_polaska+kasnjenje)/60)<<":"<<(minute_polaska+kasnjenje)%60<<".Ocekuje se da voz stigne na odrediste oko "<< sat_polaska+((minute_polaska+trajanje_voznje+kasnjenje)/60)<<":"<<(minute_polaska+trajanje_voznje+kasnjenje)%60<<".Izvinjavamo se putnicima zbog eventualnih neugodnosti."<<endl; } } Polazak::Polazak(string odrediste, int broj_voza, int broj_perona,bool brzi_voz, int sat_polaska, int minute_polaska,int trajanje_voznje):

Page 159: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

odrediste(odrediste),brzi_voz(brzi_voz) { kasnjenje=0; if (broj_voza>99999||broj_voza<0)throw "Broj voza je neispravan!"; else { Polazak::broj_voza=broj_voza; } if (sat_polaska<0||sat_polaska>24)throw "Neispravan sat polaska!"; else { Polazak::sat_polaska=sat_polaska; } if (minute_polaska<0||minute_polaska>59)throw "Neispravne minute polaska!"; else { Polazak::minute_polaska=minute_polaska; } if (broj_perona<1||broj_perona>6)throw "Neispravan broj perona!"; else { Polazak::broj_perona=broj_perona; } if (trajanje_voznje<0)throw "Neispravno trajanje voznje!"; else { Polazak::trajanje_voznje=trajanje_voznje; } } class RedVoznje { int max_broj_polazaka; int broj_polazaka; Polazak **polasci;

Page 160: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

static bool Kriterij (Polazak *a, Polazak *b) { int sati1(0), sati2(0), minute1(0), minute2(0); a->OcekivanoVrijemePolaska(sati1,minute1); b->OcekivanoVrijemePolaska(sati2,minute2); if (sati1==sati2) return minute1<minute2; else return sati1<sati2; } public: //Constructor explicit RedVoznje (int max_broj_polazaka); //Destructor ~ RedVoznje (); //Konstruktor kopije RedVoznje (const RedVoznje &red_voznje); //Operator dodjele RedVoznje &operator =(const RedVoznje &red_voznje); void RegistrirajPolazak(string odrediste, int broj_voza,bool brzi_voz, int broj_perona, int sat_polaska, int minute_polaska, int trajanje_voznje); void RegistrirajPolazak(Polazak *polazak); int DajBrojPolazaka() const { return broj_polazaka; } int DajBrojPolazakaKojiKasne() const; int DajProsjecnoTrajanjeVoznji() const; Polazak &DajPrviPolazak() const; Polazak &DajPosljednjiPolazak() const; void IsprazniKolekciju(); void Ispisi(int sati, int minute) const; };

Page 161: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

RedVoznje::RedVoznje (int max_broj_polazaka):max_broj_polazaka(max_broj_polazaka),broj_polazaka(0) { if (max_broj_polazaka<0)throw "Neispravan maksimalni broj polazaka u konstruktoru!"; polasci=0; polasci=new Polazak*[max_broj_polazaka]; for (int i=0;i<max_broj_polazaka;i++)polasci[i]=0; } RedVoznje::~ RedVoznje () { for (int i=0;i<broj_polazaka;i++)delete polasci[i]; delete []polasci; } RedVoznje::RedVoznje (const RedVoznje &red_voznje) { max_broj_polazaka=red_voznje.max_broj_polazaka; broj_polazaka=red_voznje.broj_polazaka; polasci=new Polazak*[max_broj_polazaka]; for (int i=0;i<max_broj_polazaka;i++)polasci[i]=0; for (int i=0;i<broj_polazaka;i++) polasci[i]=new Polazak(*red_voznje.polasci[i]); } RedVoznje &RedVoznje::operator =(const RedVoznje &red_voznje) { for (int i=0;i<broj_polazaka;i++)delete polasci[i]; delete []polasci; polasci=new Polazak*[red_voznje.max_broj_polazaka]; for (int i=0;i<broj_polazaka;i++)polasci[i]=0; max_broj_polazaka=red_voznje.max_broj_polazaka; broj_polazaka=red_voznje.broj_polazaka; for (int i=0;i<red_voznje.broj_polazaka;i++)polasci[i]=new Polazak(*red_voznje.polasci[i]); return *this;

Page 162: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

} void RedVoznje:: RegistrirajPolazak(string odrediste, int broj_voza,bool brzi_voz, int broj_perona, int sat_polaska, int minute_polaska, int trajanje_voznje) { if (broj_polazaka>=max_broj_polazaka)throw "Vec ste unijeli previse polazaka!"; broj_polazaka++; polasci[broj_polazaka-1]=new Polazak(odrediste,broj_voza,broj_perona,brzi_voz,sat_polaska, minute_polaska,trajanje_voznje); } void RedVoznje:: RegistrirajPolazak(Polazak *polazak) { if (broj_polazaka>=max_broj_polazaka)throw "Vec ste unijeli previse polazaka!"; broj_polazaka++; polasci[broj_polazaka-1]=polazak; } int RedVoznje:: DajBrojPolazakaKojiKasne() const { int broji(0); for (int i=0;i<broj_polazaka;i++) { if (polasci[i]->DaLiKasni())broji++; } return broji; } int RedVoznje::DajProsjecnoTrajanjeVoznji() const { int suma(0); int prosjecno(0); for (int i=0;i<broj_polazaka;i++) { suma+=polasci[i]->DajTrajanjeVoznje(); } prosjecno=suma/broj_polazaka;

Page 163: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

return prosjecno; } Polazak &RedVoznje::DajPrviPolazak() const { int sati1(0), minute1(0), pamti_polazak(0); polasci[0]->OcekivanoVrijemePolaska(sati1,minute1); for (int i=1; i<broj_polazaka; i++) { int sati2(0), minute2(0); polasci[i]->OcekivanoVrijemePolaska(sati2,minute2); if (sati2<sati1 || (sati2==sati1 && minute2<minute1)) { sati1=sati2; minute1=minute2; pamti_polazak=i; } } return *polasci[pamti_polazak]; } Polazak &RedVoznje::DajPosljednjiPolazak() const { int sati1(0), minute1(0), pamti_polazak(0); for (int i=1; i<broj_polazaka; i++) { int sati2(0), minute2(0); polasci[i]->OcekivanoVrijemePolaska(sati2,minute2); if (sati2>sati1 || (sati2==sati1 && minute2>minute1)) { sati1=sati2; minute1=minute2; pamti_polazak=i; } } return *polasci[pamti_polazak]; } void RedVoznje::IsprazniKolekciju() { for (int i=0; i<broj_polazaka; i++) {

Page 164: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

delete polasci[i]; } broj_polazaka=0; } void RedVoznje::Ispisi(int sati, int minute) const { sort(polasci, polasci+broj_polazaka, Kriterij); cout<<endl; for (int i=0; i<broj_polazaka; i++) { int s(0), m(0); polasci[i]->OcekivanoVrijemePolaska(s,m); if (s>sati || (s==sati && m>minute)) { polasci[i]->Ispisi(); } cout<<endl; } } int main() { try { // Polazak(string odrediste, int broj_voza, int broj_perona,bool brzi_voz, int sat_polaska, int minute_polaska,int trajanje_voznje); Polazak polazak1("Mostar",666, 3,true,13,10,120); polazak1.Ispisi(); polazak1.PostaviKasnjenje(70); polazak1.Ispisi(); RedVoznje red_voznje(3); red_voznje.RegistrirajPolazak(&polazak1); red_voznje.Ispisi(10,0); RedVoznje red_voznje2(red_voznje); red_voznje2.Ispisi(10,0); Polazak polazak2("Sarajevo",999,2,false,12,40,120); red_voznje2.RegistrirajPolazak(&polazak2); red_voznje2.Ispisi(9,0); red_voznje=red_voznje2;

Page 165: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

red_voznje.Ispisi(12,0); } catch (const char message[]) { cout<<message; } return 0; }

Zadaća 5. Ova zadaća nosi ukupno 3 poena, pri čemu prvi zadatak nosi 1,3 poena, drugi zadatak nosi 0,7 poena, dok treći zadatak nosi 1 poen. Sva tri zadatka se mogu uraditi na osnovu gradiva sa prvih 11 predavanja i pretpostavljenog predznanja iz predmeta “Osnove računarstva”. Rok za predaju ove zadaće je četvrtak, 7. VI 2012. (do kraja dana) i ne može se produžiti. Zadaće se predaju putem Zamgera. 1. Definirajte i implementirajte klasu “Datum” koja omogućava čuvanje datumskih podataka. Negdje u javnom dijelu klase (interfejsu) nalaze se sljedeće deklaracije: enum Mjeseci {Januar = 1, Februar, Mart, April, Maj, Jun i, Juli, August, Septembar, Oktobar, Novembar, Decembar}; enum Dani {Ponedjeljak = 1, Utorak, Srijeda, Cetvrtak, P etak, Subota, Nedjelja);

Pored ovoga, interfejs klase treba da sadrži sljedeće elemente: a) Dva konstruktora sa tri parametra koji inicijaliziraju datum u skladu sa vrijednostima za dan, mjesec i godinu koji se zadaju putem parametara. Podržana su dva načina kako se može zadati mjesec: kao vrijednost tipa “Mjeseci ” koji je lokalno definiran u interfejsu klase, ili kao cijeli broj u opsegu od 1–12 (zbog toga su i potrebna dva konstruktora). U slučaju da datum nije smislen, treba baciti izuzetak. b) Dvije metode nazvane “Postavi ” koje u načelu obavljaju isti zadatak kao i konstruktori, ali olakšavaju naknadnu promjenu pohranjenih informacija. c) Metode “DajDan ”, “ DajMjesec ” i “ DajGodinu ” koje služe za očitavanje informacija o danu, mjesecu i godini koje su pohranjene u datumu. Metode “DajDan ” i “ DajGodinu ” daju kao rezultat cijeli broj, dok metoda “DajMjesec ” daje rezultat tipa “Mjeseci ”. d) Metodu “DajImeMjeseca ” koja daje ime mjeseca koji se čuva u datumu. S obzirom da će rezultat ove funkcije uglavnom služiti samo za potrebe ispisivanja, rezultat ne treba biti tipa “string ”, nego tipa pokazivača na znakove (tako da se umjesto čitavog imena vraća se samo pokazivač na prvi znak imena). e) Metodu “DajBrojDanaUMjesecu ” koja vraća koliko ukupno dana ima onaj mjesec koji je trenutnu pohranjen u datumu. f) Metodu “DaLiJePrestupna ” vraća informaciju o tome da li je godina koja se čuva u datumu prestupna ili ne. g) Metode “DajDanUGodini ” i “ DajSedmicu ” vraćaju kao rezultat redni broj dana odnosno sedmice koji odgovaraju posmatranom datumu unutar godine koja se čuva u datumu. h) Metodu “DanUSedmici ” koja vraća dan u sedmici koji odgovara podacima zapamćenim

Page 166: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

u datumu (rezultat treba da bude tipa “Dani ” koji je lokalno definiran u interfejsu klase), kao i metodu “DajImeDanaUSedmici ” koja daje ime dana u sedmici koji odgovara datumu, na sličan način kao i metoda “DajImeMjeseca ”. i) Preklopljene operatore “++” i “ ––”, koji pomjeraju datum za jedan dan unaprijed odnosno unazad (potrebno je podržati i prefiksne i postfiksne verzije ovog operatora). j) Preklopljene operatore “+” i “ –”, pri čemu je dozvoljeno je sabrati primjerak klase “Datum” sa pozitivnim cijelim brojem, odnosno oduzeti cijeli broj od primjerka klase “Datum”, gdje se kao rezultat dobija novi primjerak klase “Datum” u kojem je datum pomjeren unaprijed odnosno unazad za broj dana iskazan drugim parametrom. Vodite računa da taj cijeli broj može biti i negativan. k) Preklopljene operatore “+=” pri čemu izrazi “d += n” odnosno “d –= n” proizvode isto dejstvo kao i izrazi “d = d + n” odnosno “d = d – n”. l) Preklopljeni operator “–” koji omogućava oduzimanje dva primjera klase “Datum”, pri čemu se kao rezultat dobija broj dana između dva datuma. m) Preklopljene relacione operatore “==”, “ != ”,“ <”,“ >”,“ <=” i “ >=” koji daju rezultat poređenja dva datuma (u hronološkom poretku, tj. manji je onaj datum koji dolazi prije po kalendaru). n) Preklopljeni operator “<<” za ispis datuma na ekran. Pri tome se prvo ispisuje redni broj dana, zatim tačka, zatim puno ime mjeseca (riječima) iza koje slijedi razmak, zatim redni broj godine iza kojeg takođe slijedi tačka i, konačno, ime odgovarajućeg dana u sedmici u zagradama. Na primjer, ukoliko je u datumu zapamćen datum 23. 5. 2012. poziv ove metode treba da na ekranu proizvede ispis “23. Maj 2012. (Srijeda) ”. o) Preklopljeni operator “<<” za unos datuma sa tastature. Datum treba da se unosi u obliku dan/ mjesec/ godina (npr. 23/ 5/ 2012), pri čemu su dan, mjesec i godina cijeli brojevi. U slučaju da unos nije ispravan (što uključuje ne samo besmislene datume nego i slučajeve da nije unesena kosa crta ili da su unesena slova umjesto brojeva, itd.), ulazni tok treba postaviti u neispravno stanje. Sve metode implementirajte izvan klase, osim trivijalnih metoda čija implementacija može stati u jedan red ekrana. Obavezno napišite i mali testni program u kojem će se testirati svi zahtijevani elementi ove klase. Uputa: Što se tiče računanja dana u sedmici koji odgovara zadanom datumu, najbolje je da prvo izračunate broj dana koji je protekao između nekog po volji izabranog referentnog datuma za koji znate na koji je dan u sedmici pao i posmatranog datuma (što nije posve baš trivijalno uraditi na efikasan način, naročito zbog prestupnih godina), a zatim izračunate ostatak dijeljenja tog broja dana sa 7. Na osnovu tog ostatka i poznate činjenice na koji je dan pao referentni datum, vrlo lako se zaključuje na koji dan pada posmatrani datum. 2. Linearne funkcije jedne realne promjenljive predstavljaju vjerovatno najviše korištene funkcije u svim oblastima nauke i tehnike. To su funkcije koje se mogu predstaviti analitičkim izrazom oblika f(x) = kx + l gdje je x realna promjenljiva, a k i l su realni parametri nazvane redom koeficijent pravca i slobodni član. Stoga je od koristi razviti opću klasu (možemo je nazvati recimo “LinFun ”) pomoću koje se mogu kreirati objekti koji se ponašaju poput linearnih funkcija sa parametrima koji se mogu zadavati prilikom kreiranja objekta (i eventualno naknadno mijenjati). Na primjer, takvi objekti mogu se koristiti kao u sljedećem primjeru: LinFun f(3, 5); // Kreira lin. funkciju nazvanu "f", f(x) = 3 x + 5 ... cout << f(2); // Ispisuje vrijednost funkcije "f" za argument 2 (11)

Pored toga, predviđeno je da se sa objektima tipa “LinFun ” mogu vršiti i različite manipulacije, u skladu sa opisom koji slijedi. Klasa “LinFun ” kao jedine svoje atribute sadrži koeficijent pravca i slobodni član odgovarajuće linearne funkcije. Definirajte i implementirajte klasu sa navedenim osobinama, znajući da njen interfejs sadrži sljedeće elemente (sve metode koje su inspektori trebaju obavezno biti označene kao takve):

Page 167: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

a) Konstruktore, koji omogućavaju kreiranje objekata tipa “LinFun ”. Predviđeno je da se objekti ovog tipa mogu kreirati na više različitih načina. Moguće je pri kreiranju zadati dva parametra, koji redom predstavljaju koeficijent pravca i slobodni član linearne funkcije koja se kreira. Dalje, moguće je zadati samo jedan parametar, koji tada predstavlja slobodni član, dok se koeficijent pravca postavlja na nulu (time se faktički kreira konstantna linearna funkcija). Konačno, objekte tipa “LinFun ” moguće je kreirati i bez zadavanja ikakvih parametara. U tom slučaju, i koeficijent pravca i slobodni član se postavljaju na nulu. Potrebno je podržati automatsku pretvorbu po kojoj se realni brojevi automatski mogu tretirati i kao konstantne linearne funkcije (tj. one sa koeficijentom pravca jednakim nuli). Napomena: mada se objekti tipa “LinFun ” mogu kreirati na tri različita načina, to ne znači nužno da moraju postojati tri konstruktora – ako možete proći sa manje, tim bolje po Vas. b) Metodu “Postavi ” sa dva parametra koja omogućava naknadnu promjenu koeficijenta pravca i slobodnog člana već definirane linearne funkcije (tj. objekta tipa “LinFun ”). c) Pristupne metode “DajKoeficijentPravca ” i “ DajSlobodniClan ” bez parametara koje omogućavaju da se saznaju vrijednosti koeficijenta pravca odnosno slobodnog člana. d) Preklopljeni unarni operator “–” koji daje kao rezultat negiranu linearnu funkciju, tj. funkciju čiji su koeficijent pravca i slobodni član negirani u odnosu na izvornu funkciju. e) Preklopljene binarne operatore “+” i “ –” koji omogućavaju da se saberu odnosno oduzmu dvije linearne funkcije, pri čemu se kao rezultati dobijaju nove linearne funkcije (njihovi koeficijenti pravca odnosno slobodni članovi jednaki su zbiru odnosno razlici koeficijenata pravca i slobodnih članova oba sabirka). Napomena: radi automatske konverzije brojeva u linearne funkcije, ovo će automatski omogućiti i sabiranje odnosno oduzimanje funkcije i broja, odnosno broja i funkcije. f) Preklopljeni binarni operator “* ” koji omogućava množenje linearne funkcije realnim brojem, odnosno realnog broja linearnom funkcijom. Kao rezultat se dobija nova linearna funkcija čiji su koeficijent pravca i slobodni član pomnoženi zadanim brojem. Množenje dvije linearne funkcije ne treba podržati, jer rezultat takvog množenja nije linearna funkcija. g) Preklopljeni binarni operator “/ ” koji omogućava dijeljenje linearne funkcije realnim brojem. Kao rezultat se dobija nova linearna funkcija čiji su koeficijent pravca i slobodni član podijeljeni zadanim brojem. Dijeljenje dvije linearne funkcije kao i dijeljenje realnog broja linearnom funkcijom ne treba podržati, jer rezultat takvog dijeljenja nije linearna funkcija. h) Preklopljene operatore “+=”, “ –=”, “ *= ” i “ /= ” koji omogućavaju da izrazi poput “X += Y ”, “ X –= Y ”, “ X *= Y ” i “ X /= Y ” imaju isto značenje kao i izrazi “X = X + Y ”, “X = X – Y ”, “ X = X * Y ” i “ X = X / Y ” kad god ovi imaju smisla. i) Preklopljene operatoe “++” i “ ––” koji povećavaju odnosno smanjuju slobodni član u linearnoj funkciji na koju je primijenjen za jedinicu. Potrebno je podržati i prefiksne i postfiksne verziju ovog operatora. j) Preklopljeni operator “() ” koji omogućava izračunavanje vrijednosti linearne funkcije za vrijednost argumenta koja se zadaje kao parametar. k) Metodu “DajInverznu ” koja daje kao rezultat novu linearnu funkciju koja je inverzna funkcija funkcije nad kojom je metoda primijenjena. Napomena: ako neka funkcija ima koeficijent pravca k i slobodni član l, njena inverzna funkcija ima koeficijent pravca 1/k i slobodni član –l/k. U slučaju dijeljenja nulom, treba baciti izuzetak. Obavezno napišite i mali testni program u kojem ćete testirati sve elemente napisane klase. 3. Za potrebe neke meteorološke stanice neophodno je vrsiti čestu registraciju količine padavina. Za tu svrhu meteorološka stanica koristi računarski program u kojem je definirana i implementirana klasa nazvana “Padavine ”. Ova klasa omogućava čuvanje podataka o

Page 168: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

količini padavina za izvjesni vremenski period u dinamički alociranom nizu cijelih brojeva, kojem se pristupa preko odgovarajućeg privatnog atributa (količina padavina se zadaje u centimetrima, zaokruženo na cijeli broj). Pored ovog atributa (i eventualno drugih privatnih atributa neophodnih za normalno funkcioniranje klase), poznato je da klasa sadrži sljedeće elemente: a) Konstruktor sa dva parametra, koji redom predstavljaju maksimalan broj količina padavina koje se mogu registrirati, odnosno maksimalno dozvoljenu količinu padavina. Ovaj konstruktor je odgovoran za dinamičku alokaciju memorije. b) Destruktor, koji oslobadja resurse koji su zauzeti od strane ove klase. c) Konstruktor kopije, koji obezbjedjuje siguran prenos objekata tipa “Padavine ” kao parametara po vrijednosti u funkcije i njihovo vraćanje kao rezultata iz funkcije, kao i preoklopljeni operator dodjele “=” koji obezbjeđuje sigurnu dodjelu jednog objekta tipa “Padavine ” drugom. d) Metodu koja vrši registraciju nove količine padavina, pri čemu se količina padavina koja se registrira prenosi kao parametar metode. U slučaju da se dostigne maksimalan broj količina padavina koje se mogu registrirati, ili u slučaju da je količina padavina manja od nule ili veća od maksimalne dozvoljene količine padavina, metoda treba da baci izuzetak. e) Metodu koja daje broj registriranih količina padavina. f) Metodu koja briše sve unesene količine padavina. g) Metode koje vraćaju kao rezultat minimalnu i maksimalnu količinu padavina (u slučaju da nema registriranih količina padavina, obje metode treba da bace izuzetak). Za realizaciju nije dozvoljeno koristiti petlje, nego odgovarajuće funkcije i/ili funktore iz biblioteka “algorithm ” i “ functional ”. h) Metode koje vraćaju kao rezultat broj dana u kojima je količina padavina bila veća odnosno manja od od vrijednosti koja se zadaje kao parametar (u slučaju da nema registriranih količina padavina, metode treba da bace izuzetak). Za realizaciju nije dozvoljeno koristiti petlje, nego odgovarajuće funkcije i/ili funktore iz biblioteka “algorithm ” i “ functional ”. i) Metodu koja ispisuje sve unesene (registrirane) količine padavina sortirane u opadajućem poretku (tj. najveća količina padavina se ispisuje prva), pri čemu se svaka količina padavina ispisuje u posebnom redu. Pri tome je neophodno koristiti funkcije i/ili funktore iz biblioteka “algorithm ” i “ functional ”. j) Preklopljeni operator “[] ” koji omogućava da se direktno pristupi i-toj registriranoj količini padavina (numeracija ide od jedinice). Ukoliko je indeks izvan dozvoljenog opsega, treba baciti izuzetak. k) Preklopljeni operator “++” koji povećava sve registrirane količine padavina za jedinicu (pri tome se za jedinicu povećava i informacija o maksimalno dozvoljenoj količini padavina). Potrebno je podržati kako prefiksnu, tako i postfiksnu verziju ovog operatora. Za realizaciju nije dozvoljeno koristiti petlje, nego odgovarajuće funkcije i/ili funktore iz biblioteka “algorithm ” i “ functional ”. l) Preklopljene operatore “+” i “- ” koji djeluju na sljedeći način: Ukoliko je “X” objekat tipa “Padavine ”, a “Y” cijeli broj, tada je “X + Y ” novi objekat tipa “Padavine ” u kojem su sve registrirane količine padavina povećane za iznos “Y” (u novodobijenom objektu treba ažurirati informaciju o maksimalno dozvoljenoj količini padavina). Na sličan način se interpretira i izraz “X - Y ” u slučaju da je “X” objekat tipa “Padavine ”, a “Y” cijeli broj. Pri tome, ukoliko se kao rezultat sabiranja ili oduzimanja dobije da neka od količina padavina postane negativna, treba baciti izuzetak. U slučaju kada su i “X” i “Y” objekti tipa “Padavine ”, tada je izraz “X - Y ” novi objekat tipa “Padavine ” koji sadrži razlike odgovarajućih količina padavina iz objekata “X” i “ Y”. U ovom posljednjem slučaju se podrazumijeva da “X” i “ Y” sadrže isti broj registriranih količina padavina, kao

Page 169: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

i da su registrirane padavine u objektu “X” veće ili jednake od odgovarajućih registriranih padavina u objektu “Y” (u suprotnom, treba baciti izuzetak). U svim ostalim slučajevima, značenje izraza “X + Y ” odnosno “X - Y ” nije definirano. Za realizaciju ovih operatora nije dozvoljeno koristiti petlje, nego odgovarajuće funkcije i/ili funktore iz biblioteka “algorithm ” i “ functional ”. m) Preklopljene operatore “+=” i “ -= ” čiji je cilj da značenje izraza oblika “X += Y ” odnosno “X –= Y ” bude identično značenju izraza “X = X + Y ” i “ X = X - Y ” kad god oni imaju smisla. n) Preklopljeni unarni operator “- ” koji daje kao rezultat novi objekat tipa “Padavine ” u kojem su sve količine padavina oduzete od maksimalno dozvoljene količine padavina. Za realizaciju nije dozvoljeno koristiti petlje, nego odgovarajuće funkcije i/ili funktore iz biblioteka “algorithm ” i “ functional ”. o) Preklopljene relacione operatore “==” i “ != ” koje ispituju da li su dva objekta tipa “Padavine ” jednaka ili nisu. Dva objekta ovog tipa smatraju se jednakim ukoliko sadrže isti broj registriranih količina padavina, i ukoliko su sve odgovarajuće registrirane količine padavina oba objekta jednake. Za realizaciju ovih operatora nije dozvoljeno koristiti petlje, nego odgovarajuće funkcije i/ili funktore iz biblioteka “algorithm ” i “ functional ”. Implementirajte klasu sa navedenim svojstvima. Sve neophodne atribute treba obavezno izvesti kao privatne članove klase, a sve metode implementirajte izvan klase, osim metoda čija je implementacija dovoljno kratka, u smislu da zahtijeva recimo jednu ili dvije naredbe. Obavezno napišite i mali testni program u kojem će se testirati sve elemente napisane klase.

1.DATUMI

#include <iostream> using namespace std; class Datum { int dan; int mjesec; int godina; public: enum Mjeseci{Januar=1,Februar,Mart,April,Maj,Juni,Juli,August,Septembar,Oktobar,Novembar,Decembar}; enum Dani{Ponedjeljak=1,Utorak,Srijeda,Cetvrtak,Petak,Subota,Nedjelja}; //Constructors Datum(int d,int m, int g) { int broj_dana[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if (g % 4 == 0 && g % 100 != 0 || g % 400 == 0) broj_dana[1]++;

Page 170: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

if ((g < 1 )|| (d < 1) || (m < 1) ||( m > 12) ||(d>broj_dana[m-1]))throw "Neispravan datum!\n"; dan = d; mjesec = m; godina = g; } Datum(int d,Mjeseci m, int g) { int broj_dana[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if (g % 4 == 0 && g % 100 != 0 || g % 400 == 0) broj_dana[1]++; if (g < 1 || d < 1 || m < 1 || m > 12 || d > broj_dana[m-1]) throw "Neispravan datum!\n"; dan = d; mjesec = m; godina = g; } //Methods void Postavi(int d,int m,int g); void Postavi(int d, Mjeseci m,int g); int DajDan()const { return dan; } Mjeseci DajMjesec()const; int DajGodinu()const { return godina; }; const char *DajImeMjeseca()const; int DajBrojDanaUMjesecu()const; bool DaLiJePrestupna()const; int DajDanUGodini()const; int DajSedmicu()const; int DanUSedmici()const; const char*DajImeDanaUSedmici()const; //operatori friend Datum &operator++(Datum &d);

Page 171: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

friend Datum operator++(Datum &d,int);//postfiksni friend Datum &operator--(Datum &d); friend Datum operator--(Datum &d,int);//postfiksni friend Datum operator+(const Datum &d,int n); friend Datum operator-(const Datum &d,int n); friend void operator+=(Datum &d,int n); friend void operator-=(Datum &d,int n); friend int operator-(const Datum &d1,const Datum &d2); friend bool operator==(const Datum &d1,const Datum &d2); friend bool operator!=(const Datum &d1,const Datum &d2); friend bool operator >(const Datum &d1,const Datum &d2); friend bool operator<(const Datum &d1,const Datum &d2); friend bool operator >=(const Datum &d1,const Datum &d2); friend bool operator <=(const Datum &d1,const Datum &d2); friend ostream &operator<<(ostream &cout,const Datum &d); friend istream &operator>>(istream &cin, Datum &v); }; Datum::Mjeseci Datum::DajMjesec()const { if (mjesec==1) return Januar; if (mjesec==2)return Februar; if (mjesec==3) return Mart; if (mjesec==4)return April; if (mjesec==5)return Maj; if (mjesec==6)return Juni; if (mjesec==7)return Juli; if (mjesec==8) return August; if (mjesec==9) return Septembar; if (mjesec==10)return Oktobar; if (mjesec==11)return Novembar; if (mjesec==12)return Decembar; } void Datum:: Postavi(int d,int m,int g) { int broj_dana[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if (g % 4 == 0 && g % 100 != 0 || g % 400 == 0) broj_dana[1]++; if (g < 1 || d < 1 || m < 1 || m > 12 || d > broj_dana[m-1]) throw "Neispravan datum!\n"; dan = d;

Page 172: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

mjesec = m; godina = g; } void Datum:: Postavi(int d, Mjeseci m,int g) { int broj_dana[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if (g % 4 == 0 && g % 100 != 0 || g % 400 == 0) broj_dana[1]++; if (g < 1 || d < 1 || m < 1 || m > 12 || d > broj_dana[m-1]) throw "Neispravan datum!\n"; dan = d; mjesec = m; godina = g; } const char* Datum::DajImeMjeseca()const { const char *imena[12] = {"Januar", "Februar", "Mart", "April", "Maj", "Juni", "Juli", "August", "Septembar", "Oktobar", "Novembar", "Decembar" }; return imena[mjesec-1]; } int Datum ::DajBrojDanaUMjesecu()const { if (mjesec==1)return 31; if (mjesec==2) { if (DaLiJePrestupna())return 29; return 28; } if (mjesec==3)return 31; if (mjesec==4)return 30; if (mjesec==5) return 31; if (mjesec==6) return 30; if (mjesec==7) return 31; if (mjesec==8)return 31; if (mjesec==9) return 30; if (mjesec==10) return 31; if (mjesec==11)return 30;

Page 173: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

if (mjesec==12)return 31; } bool Datum:: DaLiJePrestupna()const { if (godina % 4 == 0 && godina % 100 != 0 || godina % 400 == 0)return true; return false; } int Datum::DajDanUGodini()const { if (mjesec==1)return dan; if (mjesec==2)return dan+ 31; if (mjesec==3) { if (DaLiJePrestupna())return dan+31+29; return dan+31+28; } if (mjesec==4) { if (DaLiJePrestupna())return dan+31+29+31; return dan+31+28+31; } if (mjesec==5) { if (DaLiJePrestupna())return dan+31+29+31+30; return dan+31+28+31+30; } if (mjesec==6) { if (DaLiJePrestupna())return dan+31+29+31+30+31; return dan+31+28+31+30+31; } if (mjesec==7) { if (DaLiJePrestupna())return dan+31+29+31+30+31+30; return dan+31+28+31+30+31+30; } if (mjesec==8) { if (DaLiJePrestupna())return dan+31+29+31+30+31+30+31; return dan+31+28+31+30+31+30+31;

Page 174: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

} if (mjesec==9) { if (DaLiJePrestupna())return dan+31+29+31+30+31+30+31+31; return dan+31+28+31+30+31+30+31+31; } if (mjesec==10) { if (DaLiJePrestupna())return dan+31+29+31+30+31+30+31+31+30; return dan+31+28+31+30+31+30+31+31+30; } if (mjesec==11) { if (DaLiJePrestupna())return dan+31+29+31+30+31+30+31+31+30+31; return dan+31+28+31+30+31+30+31+31+30+31; } if (mjesec==12) { if (DaLiJePrestupna())return dan+31+29+31+30+31+30+31+31+30+31+30; return dan+31+28+31+30+31+30+31+31+30+31+30; } } int Datum::DajSedmicu()const { return (DajDanUGodini()/7); //prvi mjesec uvijek ima 5 sedmica koje su nacete } int Datum::DanUSedmici()const { int pomMjeseci[12]={0,3,3,6,1,4,6,2,5,0,3,5}; int prvo=dan+pomMjeseci[mjesec-1]; int zadnjecifre=godina%100; int danro=(((zadnjecifre)+(zadnjecifre%100)/4)+prvo)%7; if ((godina/1000)%2==1) {

Page 175: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

if (danro==0)return 7; return danro; } else { if (DaLiJePrestupna()&&DajMjesec()==2) { if (danro==0)return 5; if (danro==1)return 6; return danro-2; } if (danro==0)return 6; if (danro==1)return 7; return danro-1; } } const char* Datum::DajImeDanaUSedmici()const { const char*imena[7]={"Ponedjeljak","Utorak","Srijeda","Cetvrtak","Petak","Subota","Nedjelja"}; return imena[DanUSedmici()-1]; } Datum &operator++(Datum &d)//prefiksni { if ( d.DajBrojDanaUMjesecu()==d.dan) { if (d.mjesec==12) { d.godina++; d.mjesec=1; d.dan=1; } else { d.mjesec++; d.dan=1; } return d;

Page 176: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

} else { d.dan++; return d; } } Datum operator++(Datum &d,int)//postfiksni { Datum v(d.dan,d.mjesec,d.godina); if ( d.DajBrojDanaUMjesecu()==d.dan) { if (d.mjesec==12) { d.godina++; d.mjesec=1; d.dan=1; } else { d.mjesec++; d.dan=1; } return v; } else { d.dan++; return v; } } Datum &operator--(Datum &d) { if ( d.dan=1) { if (d.mjesec==1) { d.godina--; d.mjesec=12;

Page 177: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

d.dan=31; } else { d.mjesec--; d.dan=d.DajBrojDanaUMjesecu(); } return d; } else { d.dan--; return d; } } Datum operator--(Datum &d,int)//postfiksni { Datum v(d.dan,d.mjesec,d.godina); if ( d.dan==1) { if (d.mjesec==1) { d.godina--; d.mjesec=12; d.dan=31; } else { d.mjesec--; d.dan=d.DajBrojDanaUMjesecu(); } return v; } else { d.dan--; return v; } } Datum operator+(const Datum &d,int n)

Page 178: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

{ if (n<=0)throw "Nije definirano pomjeranje datuma sa negativnim brojevima!"; int danNovi,mjesecNovi,godinaNova; danNovi=d.dan; mjesecNovi=d.mjesec; godinaNova=d.godina; Datum novi(danNovi,mjesecNovi,godinaNova); for (int i=0;i<n;i++) { novi++; } return novi; } Datum operator-(const Datum &d,int n) { if (n<=0)throw "Nije definirano pomjeranje datuma sa negativnim brojevima!"; Datum novi(d.dan,d.mjesec,d.godina); for (int i=0;i<n;i++) { novi--; } return novi; } void operator+=(Datum &d,int n) { d=d+n; } void operator-=(Datum &d,int n) { d=d-n; } int operator-(const Datum &d1,const Datum &d2) { int dani(((d1.godina-d2.godina)*365)+((d1.godina-d2.godina)/4));

Page 179: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

if (d1.DaLiJePrestupna()) { if (dani<0)dani--; else dani++; } if (d2.DaLiJePrestupna()) { if (dani<0)dani--; else dani++; } return ((d1.DajDanUGodini()-d2.DajDanUGodini())+dani); } bool operator==(const Datum&d1,const Datum &d2) { if (d1.dan==d2.dan &&d1.mjesec==d2.mjesec&&d1.godina==d2.godina)return true; return false; } bool operator!=(const Datum &d1,const Datum &d2) { return !(d1==d2); } bool operator >(const Datum &d1,const Datum &d2) { if (d1.godina>d2.godina)return true; else { if (d1.godina==d2.godina) { if (d1.mjesec>d2.mjesec) return true; else { if (d1.mjesec==d2.mjesec) { if (d1.dan>d2.dan)return true; else return false;

Page 180: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

} return false; } } return false; } } bool operator >=(const Datum &d1,const Datum &d2) { if (d1.godina==d2.godina&&d1.mjesec==d2.mjesec&&d1.dan==d2.dan)return true; return d1>d2; } bool operator <(const Datum &d1,const Datum &d2) { if (d1.godina==d2.godina&&d1.mjesec==d2.mjesec&&d1.dan==d2.dan)return false; return !(d1>d2); } bool operator <=(const Datum &d1,const Datum &d2) { if (d1.godina==d2.godina&&d1.mjesec==d2.mjesec&&d1.dan==d2.dan)return true; return !(d1>d2); } ostream &operator<<(ostream &cout,const Datum &d) { cout<<d.dan<<". "<<d.DajImeMjeseca()<<" "<<d.godina<<". ("<<d.DajImeDanaUSedmici ()<<")"; return cout; } istream &operator>>(istream &cin, Datum &v) { char znak; cin>>ws; int danp,mjesecp,godinap; int broj_dana[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; cin>>danp; if (danp < 1|| danp >31)cin.setstate(ios::failbit);

Page 181: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

cin>>znak; if (znak!='/')cin.setstate(ios::failbit); cin>>mjesecp; if ( danp < 1 || mjesecp < 1 || mjesecp > 12 || danp > broj_dana[mjesecp-1])cin.setstate(ios::failbit); cin>>znak; if (znak!='/')cin.setstate(ios::failbit); cin>>godinap; if (godinap % 4 == 0 && godinap % 100 != 0 || godinap % 400 == 0) broj_dana[1]++; if (godinap < 1 || danp < 1 || mjesecp < 1 || mjesecp > 12 || danp > broj_dana[mjesecp-1])cin.setstate(ios::failbit); v.dan=danp; v.mjesec=mjesecp; v.godina=godinap; return cin; } int main() { /*Datum b(1,1,2010); cout<<endl<<b.DajDanUGodini(); cout<<endl<<"Sedmica:"<<b.DajSedmicu()<<endl;; cout<<endl<<b.DaLiJePrestupna(); cout<<endl<<"Dan u sedmici->"<<b.DanUSedmici()<<" "<<b.DajImeDanaUSedmici(); cout<<endl<<b.DajImeDanaUSedmici(); b--; cout<<endl<<b.DajImeDanaUSedmici(); b+=55; cout<<endl<<"Novi datum->"<<b; cout<<"\nporedjenje->"<<(Datum(1,1,2015)>=Datum(1,1,2014)); cin>>b;*/ /* Datum d(3,1,2010);

Page 182: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

d++; cout<<d.DajDan()<<" "<<d.DajImeMjeseca()<<" "<<d.DajGodinu()<<" "<<d.DajDanUGodini()<<" "<<d.DajSedmicu()<<" "<<d.DajImeDanaUSedmici()<<" "; d+=4; cout<<d.DajDan()<<" "<<d.DajImeMjeseca()<<" "<<d.DajGodinu()<<" "<<d.DajDanUGodini()<<" "<<d.DajSedmicu()<<" "<<d.DajImeDanaUSedmici();*/ cout<<Datum(20,6,2010)-Datum(20,5,2010); return 0; } 2.LINEARNE FUNKCIJE #include <iostream> using namespace std; class LinFun { double koeficijent_pravca; double slobodni_clan; public: //Constructors LinFun(double koeficijent_pravca,double slobodni_clan):koeficijent_pravca(koeficijent_pravca),slobodni_clan(slobodni_clan){}; LinFun():koeficijent_pravca(0),slobodni_clan(0){}; //za automatsku konverziju LinFun(double slobodni_clan):koeficijent_pravca(0),slobodni_clan(slobodni_clan){} //Methods void Postavi(double koeficijent,double slobodni); double DajKoeficijentPravca()const { return koeficijent_pravca; } double DajSlobodniClan()const { return slobodni_clan; } LinFun DajInverznu()const; //Operators //Binarni friend void operator-(LinFun &f); friend LinFun operator+(const LinFun &f1,const LinFun &f2); friend LinFun operator-(const LinFun &f1,const LinFun &f2); friend LinFun operator*(const LinFun &f,double b); friend LinFun operator*(double b,const LinFun &f);

Page 183: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

friend LinFun operator/(const LinFun &f,double b); //Unarni friend LinFun &operator+=(LinFun &f1,const LinFun &f2); friend LinFun &operator-=(LinFun &f1,const LinFun &f2); friend LinFun &operator*=(LinFun &f1,double b); friend LinFun &operator*=(double b,LinFun&f1); friend LinFun &operator/=(LinFun &f1,double b); friend LinFun &operator++(LinFun &f); friend LinFun operator++(LinFun &f,int); friend LinFun &operator--(LinFun &f); friend LinFun operator--(LinFun &f,int); double operator()(double b); }; //Methods void LinFun::Postavi(double koeficijent,double slobodni) { koeficijent_pravca=koeficijent; slobodni_clan=slobodni; } LinFun LinFun::DajInverznu()const { LinFun inverzna; if (koeficijent_pravca==0)throw "Koeficijent pravca je nula,a dijeljenje s nulom nije definirano!"; else { inverzna.koeficijent_pravca=1/koeficijent_pravca; inverzna.slobodni_clan=-(slobodni_clan/koeficijent_pravca); } return inverzna; } //Operators void operator-(LinFun &f) { f.koeficijent_pravca=-f.koeficijent_pravca; f.slobodni_clan=-f.slobodni_clan; } LinFun operator+(const LinFun &f1,const LinFun &f2) { LinFun f3; f3.koeficijent_pravca=f1.koeficijent_pravca+f2.koeficijent_pravca;

Page 184: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

f3.slobodni_clan= f1.slobodni_clan+f2.slobodni_clan; return f3; } LinFun operator-(const LinFun &f1,const LinFun &f2) { LinFun f3; f3.koeficijent_pravca=f1.koeficijent_pravca-f2.koeficijent_pravca; f3.slobodni_clan= f1.slobodni_clan-f2.slobodni_clan; return f3; } LinFun operator*(const LinFun &f,double b) { LinFun r; r.koeficijent_pravca=f.koeficijent_pravca*b; r.slobodni_clan=f.slobodni_clan*b; return r; } LinFun operator*(double b,const LinFun &f) { return f*b; } LinFun operator/(const LinFun &f,double b) { LinFun r; r.koeficijent_pravca=f.koeficijent_pravca/b; r.slobodni_clan=f.slobodni_clan/b; return r; } LinFun &operator+=(LinFun &f1,const LinFun &f2) { f1.koeficijent_pravca+=f2.koeficijent_pravca; f1.slobodni_clan+=f2.slobodni_clan; return f1; } LinFun &operator-=(LinFun &f1,const LinFun &f2) { f1.koeficijent_pravca-=f2.koeficijent_pravca; f1.slobodni_clan-=f2.slobodni_clan; return f1; } LinFun &operator*=(LinFun &f1,double b) {

Page 185: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

f1.koeficijent_pravca*=b; f1.slobodni_clan*=b; return f1; } LinFun &operator*=(double b,LinFun &f1) { return f1*=b; } LinFun &operator/=(LinFun &f1,double b) { f1.koeficijent_pravca/=b; f1.slobodni_clan/=b; } LinFun &operator++(LinFun &f) { f.slobodni_clan+=1; return f; } LinFun operator++(LinFun &f,int) { LinFun pom(f); f.slobodni_clan+=1; return pom; } LinFun &operator--(LinFun &f) { f.slobodni_clan-=1; return f; } LinFun operator--(LinFun &f,int) { LinFun pom(f); f.slobodni_clan-=1; return pom; } double LinFun:: operator()(double b)

Page 186: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

{ double vrijednost; vrijednost=koeficijent_pravca*b+slobodni_clan; return vrijednost; } int main() { LinFun f1(3,2); cout<<f1.DajKoeficijentPravca()<<" "<<f1.DajSlobodniClan(); LinFun f2(3,4); cout<<endl<<f2.DajKoeficijentPravca(); cout<<" Slobodni->"<<f2.DajSlobodniClan(); f2=f2+f1; f1=++f2; cout<<endl<<f2.DajKoeficijentPravca()<<" "<<f2.DajSlobodniClan(); cout<<endl<<f1.DajKoeficijentPravca()<<" "<<f1.DajSlobodniClan(); cout<<endl<<f1(2); cout<<endl<<f1.DajInverznu().DajSlobodniClan(); LinFun f5;//poziv konstruktora bez parametara f5=4;//upotreba automatske konverzije cout<<"\nSlobodni clan->"<<f5.DajSlobodniClan()<<endl; f5=4.5; cout<<"\nSlobodni clan->"<<f5.DajSlobodniClan()<<endl; try{ f5.DajInverznu(); } catch(const char*p) { cout<<p; } return 0; }

Page 187: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

3.PADAVINE #include <iostream> #include <algorithm> #include "TestCurenja.h" using namespace std; class Padavine { int maks_broj_kolicina_padavina; int maks_dozvoljena_kolicina_padavina; int broj_registriranih_padavina; int *padavine; static bool Kriterij(int a,int b) { return a > b; } public: //Constructor Padavine(int maks_broj_kolicina_padavina,int maks_dozvoljena_kolicina_padavina):padavine(new int[maks_broj_kolicina_padavina]),maks_broj_kolicina_padavina(maks_broj_kolicina_padavina), maks_dozvoljena_kolicina_padavina(maks_dozvoljena_kolicina_padavina),broj_registriranih_padavina(0) { for (int i=0;i<maks_broj_kolicina_padavina;i++)padavine[i]=0; } //Destructor ~Padavine() { delete []padavine; } //Constructor-copy Padavine(const Padavine &p); //Operator dodjele Padavine &operator=(const Padavine&p); //Methods void Dodaj(int p); int DajBrojRegistriranihKolicinaPadavina()const { return broj_registriranih_padavina;

Page 188: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

} void Brisi(); int DajMin()const; int DajMaks()const; int DajBrojVecihOd(int n)const; int DajBrojManjihOd(int n)const; void Ispisi()const; //operatori int& operator[](int n); friend Padavine& operator++(Padavine &p); friend Padavine operator++(Padavine &p,int); friend Padavine operator+(Padavine &p,int n); friend Padavine operator-(const Padavine &p,int n); friend Padavine operator-(const Padavine &p1,const Padavine &p2); friend void operator+=(Padavine &p,int n); friend void operator-=(Padavine &p1,const Padavine &p2); friend void operator-=(Padavine &p,int n); friend Padavine operator-(Padavine&p); friend bool operator==(const Padavine &p1, const Padavine &p2); friend bool operator!=(const Padavine &p1, const Padavine &p2); }; //Constructor copy Padavine::Padavine(const Padavine &p) { maks_broj_kolicina_padavina = p.maks_broj_kolicina_padavina; maks_dozvoljena_kolicina_padavina = p.maks_dozvoljena_kolicina_padavina; broj_registriranih_padavina = p.broj_registriranih_padavina; padavine=new int [p.maks_broj_kolicina_padavina]; for (int i=0;i<p.broj_registriranih_padavina;i++) padavine[i]=p.padavine[i]; } //Operator= Padavine &Padavine::operator=(const Padavine&p) { if (maks_broj_kolicina_padavina<p.maks_broj_kolicina_padavina) { delete []padavine;

Page 189: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

padavine=new int[p.maks_broj_kolicina_padavina]; } broj_registriranih_padavina=p.broj_registriranih_padavina; maks_dozvoljena_kolicina_padavina=p.maks_dozvoljena_kolicina_padavina; maks_broj_kolicina_padavina=p.maks_broj_kolicina_padavina; copy(p.padavine,p.padavine+p.broj_registriranih_padavina,padavine); return *this; } //Methods void Padavine::Dodaj(int p) { if (broj_registriranih_padavina==maks_broj_kolicina_padavina)throw "Nije moguce vise dodavati padavina,dosegnut je maksimalni broj"; if (p>maks_dozvoljena_kolicina_padavina||p<0)throw "Kolicina padavine koju unosite nema legalnu vrijednost!"; padavine[broj_registriranih_padavina++]=p; } void Padavine::Brisi() { for (int i=0;i<broj_registriranih_padavina;i++) padavine[i]=0; broj_registriranih_padavina=0; } int Padavine::DajMin()const{ if(broj_registriranih_padavina==0)throw "Nema registriranih padavina!"; int min(*(min_element(padavine,padavine+broj_registriranih_padavina))); return min; } int Padavine::DajMaks()const{ if(broj_registriranih_padavina==0)throw "Nema registriranih padavina!"; int maks(*(max_element(padavine,padavine+broj_registriranih_padavina))); return maks; }

Page 190: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

int Padavine::DajBrojVecihOd(int n)const{ if(broj_registriranih_padavina<0)throw "Nema registriranih padavina."; return count_if(padavine, padavine+broj_registriranih_padavina, bind2nd(greater<int>(), n)); } int Padavine::DajBrojManjihOd(int n)const{ if(broj_registriranih_padavina<0)throw "Nema registriranih padavina."; return count_if(padavine, padavine+broj_registriranih_padavina, bind2nd(less<int>(), n)); } void Padavine::Ispisi()const{ Padavine pom(*this); sort(pom.padavine,pom.padavine+broj_registriranih_padavina,Kriterij); for(int i=0;i<broj_registriranih_padavina;i++) cout<<endl<<pom.padavine[i]; } int&Padavine:: operator[](int n){ if(n<=0||n>broj_registriranih_padavina) throw "Indeks nije u dozvoljenom opsegu!"; return padavine[n-1]; } void Uvecaj (int &n) { n++; } Padavine& operator++(Padavine &p){ for_each(p.padavine, p.padavine+p.broj_registriranih_padavina, Uvecaj); p.maks_broj_kolicina_padavina++; return p; } Padavine operator++(Padavine &p,int){ Padavine pom(p); for_each(p.padavine, p.padavine+p.broj_registriranih_padavina, Uvecaj); p.maks_broj_kolicina_padavina++; return pom; }

Page 191: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

Padavine operator+(Padavine &p,int n){ for(int i=0;i<p.broj_registriranih_padavina;i++){p.padavine[i]=p.padavine[i]+n; if(p.padavine[i]<0)throw "Kolicina padavina ne smije biti negativna!";} p.maks_dozvoljena_kolicina_padavina=p.maks_dozvoljena_kolicina_padavina+n; return p; } Padavine operator-(const Padavine &p,int n){ for(int i=0;i<p.broj_registriranih_padavina;i++){p.padavine[i]=p.padavine[i]-n; if(p.padavine[i]<0)throw "Kolicina padavina ne smije biti negativna!"; } return p; } Padavine operator-(const Padavine &p1,const Padavine &p2){ Padavine pom(p1); for(int i=0;i<p1.broj_registriranih_padavina;i++){pom.padavine[i]=p1.padavine[i]-p2.padavine[i]; if(pom.padavine[i]<0)throw "Kolicina padavina ne smije biti negativna!"; } return pom; } void operator+=(Padavine &p,int n){p=p+n;} void operator-=(Padavine &p1,const Padavine &p2){p1=p1-p2;} void operator-=(Padavine &p,int n){p=p-n;} Padavine operator-( Padavine &p){ Padavine pom(p); fill(pom.padavine, pom.padavine+pom.broj_registriranih_padavina, pom.maks_dozvoljena_kolicina_padavina); // for(int i=0;i<p.broj_registriranih_padavina;i++)p.padavine[i]=p.maks_dozvoljena_kolicina_padavina-p.padavine[i]; pom=pom-p; return pom; } bool operator==(const Padavine &p1, const Padavine &p2){

Page 192: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

if(p1.broj_registriranih_padavina!=p2.broj_registriranih_padavina) return false; //for(int i=0;i<p1.broj_registriranih_padavina;i++)if(p1.padavine[i]!=p2.padavine[i])return false; return (equal(p1.padavine, p1.padavine+p1.broj_registriranih_padavina, p2.padavine, equal_to<int>())); } bool operator!=(const Padavine &p1, const Padavine &p2){return !(p1==p2);} int main() { Padavine p(3,400); Padavine d(p); try { p.Dodaj(7); p.Dodaj(3); p.Dodaj(45); cout<<p.DajMin(); cout<<endl<<p.DajMaks(); } catch (const char p[]) { cout<<p; } p.Ispisi(); cout<<endl<<p[1]; ++p; p.Ispisi(); p++.Ispisi(); p.Ispisi(); p-=3; p.Ispisi(); Padavine p2(p); p=(-p); Padavine p3(p2); p.Ispisi(); cout<<endl<<(p2!=p3)<<endl<<p.DajBrojVecihOd(5); return 0; }

Page 193: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

Zadaća 6. Ova zadaća nosi ukupno 3,4 poena, pri čemu prvi zadatak nosi 1,1 poen, drugi zadatak nosi 1,5 poen, dok treći zadatak nosi 0,8 poena. Sva tri zadatka se mogu uraditi na osnovu gradiva sa prvih 13 predavanja i pretpostavljenog predznanja iz predmeta “Osnove računarstva”. Rok za predaju ove zadaće je četvrtak, 14. VI 2012. (do kraja dana) i ne može se produžiti (nemojte pitati može li se produžiti do dana ispita – ne može). Zadaće se predaju putem Zamgera. Napomena: Nije greška činjenica da sve zadaće zajedno nose 22 a ne 20 poena (dva dodatna poena su kompenzacioni poeni). 1. U raznim oblastima matematike često se javlja potreba za radom sa skupovima. Jezik C++ sadrži standardnu biblioteku “set ” i istoimeni tip podataka koja omogućava rad sa skupovima. Zbog nedostatka prostora, ova biblioteka i ovaj tip podataka nisu razmatrani na kursu Tehnika programiranja, međutim zainteresirani mogu lako pronaći (recimo, na internetu) informacije o tome kako se ovaj tip podataka može koristiti. Međutim, ovdje je Vaš zadatak da sami razvijete generičku klasu “Skup ” slične funkcionalnosti (koja doduše neće ni izbliza biti efikasna koliko je bibliotečki tip podataka “set ”, pogotovo kada je broj pohranjenih podataka velik, ali za vježbu će lijepo poslužiti). Generička klasa “Skup ” će predstavljati skup čiji elementi mogu biti proizvoljnog, ali istog tipa. Drugim riječima, svi elementi skupa moraju biti istog tipa, tako da skupovi heterogenog sastava neće biti podržani. Pored toga, za elemente skupa ćemo pretpostaviti da se mogu porediti pomoću operatora “<” (nije na odmet znati da bibliotečki tip podataka “set ” posjeduje ista ova ograničenja). Klasa treba da ima sljedeće elemente: a) Privatni atribut koji predstavlja vektor u kojem se interno čuvaju elementi skupa (ovo će ujedno biti jedini atribut klase, tako da čitava klasa zapravo predstavlja pogodan “omotač” oko standardnog tipa podataka “vector ”). b) Konstruktor bez parametara, koji kreira prazan skup. c) Konstruktor koji prima jedan parametar tipa vektor, čiji su elementi istog tipa kao što je pretpostavljeni tip elemenata skupa. Ovaj konstruktor kreira skup na osnovu elemenata vektora. Osnovna namjena ovog konstruktora je da podrži pretvorbu podataka tipa “vector ” u odgovarajući tip “Skup ”. S obzirom da prema matematskoj definiciji skupa skupovi ne mogu sadržavati jednake elemente, prilikom kreiranja skupa višestruko ponavljanje elemenata u vektoru treba ignorirati. Na primjer, ukoliko je vektor sadržavao redom elemente 3, 5, 2, 8, 2, 5, 2 i 1, kreirani skup sadržavaće elemente 3, 5, 2, 8 i 1. d) Konstruktor koji prima dva parametra, pri čemu je prvi parametar niz čiji su elementi istog tipa kao što je pretpostavljeni tip elemenata skupa, dok drugi parametar predstavlja broj elemenata u nizu. Ovaj konstruktor ima istu namjenu kao i prethodni, samo što je neophodan i dodatni parametar, s obzirom da se broj elemenata niza koji se prenosi kao parametar ne može saznati iz samog niza. e) Metodu “DodajElement ” sa jednim parametrom, koja dodaje u skup element predstavljen parametrom. U slučaju da se takav element već nalazi u skupu, unos elementa treba ignorirati. f) Metodu “DajKardinalniBroj ” bez parametara, koja vraća kao rezultat broj elemenata skupa. g) Metodu “DaLiSadrzi ” sa jednim parametrom, koja vraća kao rezultat “true ” ukoliko se element predstavljen parametrom nalazi u skupu, a “false ” ukoliko se ne nalazi. h) Preklopljen unarni operator “! ”, koji primijenjen na skup daje “true ” ukoliko je skup prazan, a “false ” ukoliko nije. i) Preklopljen operator “<<” koji treba da podrži ispis skupova na ekran. Skupovi se ispisuju kao slijed svojih elemenata unutar vitičastih zagrada, međusobno razdvojenih zarezima. Pri ispisu, elementi treba da budu sortirani u rastući poredak (redoslijed elemenata je kod skupova svakako nebitan). Za sortiranje možete koristiti funkiju “sort ”

Page 194: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

(bez funkcije kriterija, jer je pretpostavljeno da su elementi skupa takvi da je za njih definiran poredak uz pomoć operatora “<”). j) Preklopljene binarne operatore “+”, “ * ” i “ - ” koji redom nalaze uniju, presjek i razliku skupova koji su navedeni kao operandi. k) Prekopljene binarne operatore “+=”,“ *= ” i “ –=” pri čemu izrazi poput “A += B ”, “A *= B ” i “ A –= B ” predstavljaju respektivno skraćene zapise za izraze “A = A + B ”, “A = A * B ” i “ A = A – B ”. l) Preklopljene binarne relacione operatore “<=”,“ >=”,“ ==”,“ != ”,“ <” i “ >” pri čemu relacije “A <= B ”, “ A >= B ”, “ A == B ”, “ A != B ”, “ A < B ” i “ A > B ” predstavljaju respektivno odnose “A je podskup od B”, “ A je nadskup od B”, “ A i B su jednaki”, “A i B su različiti”, “A je pravi podskup od B”, “ A je pravi nadskup od B”. Uputa: Prvo definirajte operator “<=”. Dalje, vrijedi “A >= B ” ako je “B <= A ”. Vrijedi “ A == B ” ako je “A >= B ” i “A <= B ”. Vrijedi “ A != B ” ako nije “A == B ”. Vrijedi “ A < B ” ako je “A <= B ” i “A != B ”. Vrijedi “ A > B ” ako je “A >= B ” i “ A != B ” (primijetite da za ovako definiran poredak izrazi “A < B ” i “ A >= B ” nisu nužno negacija jedan drugog). Dakle, sve relacione operatore možete definirati polazeći samo od operatora “<=”. Primijetimo da destruktor, konstruktor kopije i preklopljeni operator dodjele neće biti potrebni za ispravno funkcioniranje klase, s obzirom da se svi elementi skupa čuvaju u vektoru, koji se brine za automatsko upravljanje memorijom. Sve metode implementirajte izvan deklaracije klase, osim trivijalnih metoda koje trebate implementirati direktno unutar deklaracije klase. Obavezno napišite i testni program u kojem ćete demonstrirati sve elemente napisane generičke klase uzimajući stringove (tj. objekte tipa “string ”) za elemente skupova. 2. Uprava ETF-a odlučila je da uvede automatizirani fast-food restoran. Za potrebe automatske obrade narudžbi, potrebno je razviti program zasnovan na skupini klasa, prema opisu koji slijedi. Klasa “Obrok ” opisuje najjednostavniju narudžbu, koja predstavlja neki obrok. Ova klasa od atributa sadrži naziv obroka (recimo “Burek”), cijenu obroka (realan broj) i puno ime (sa prezimenom) studenta koji je naručio obrok. Pored ovih atributa, klasa sadrži konstruktor koji inicijalizira atribute na vrijednosti zadane parametrima, trivijalne pristupne metode “DajNazivObroka ”, “ DajCijenuObroka ” i “ DajNarucioca ” koje vraćaju vrijednost svih atributa, metodu “Ispisi ” koja ispisuje podatke o izvršenoj narudžbi (ispis formatirajte prema vlastitoj želji) kao i metodu “DajUkupnuCijenu ” koja vraća ukupnu cijenu narudžbe. U slučaju klase “Obrok ”, ova metoda će samo vratiti cijenu obroka pohranjenu u atributu, ali treba predvidjeti da će ova metoda biti eventualno izmijenjena u složenijim klasama naslijeđenim iz klase “Obrok ” kod kojih se ukupna cijena obroka formira na složeniji način. Konačno, klasa sadrži i metodu “DajKopiju ” koja kreira dinamički alociranu kopiju objekta nad kojim je pozvana (ova metoda će se koristiti za polimorfno kopiranje). Bitno je da treba biti omogućeno da se preko pokazivača na klasu “Obrok ” uvijek pozivaju ispravne verzije svih metoda koje eventualno mogu biti promijenjene u naslijeđenim klasama, bez obzira na tip objekta na koji taj pokazivač pokazuje u trenutku poziva. Klasa “ObrokSaPicem ” opisuje narudžbu koja uz obrok uključuje i piće. Ova klasa naslijeđena je iz klase “Obrok ”, a od dodatnih atributa sadrži i naziv pića (recimo “Fanta”) kao i cijenu pića. U skladu s tim, klasa ima i dvije nove trivijalne pristupne metode “DajNazivPica ” i “ DajCijenuPica ” koje vraćaju vrijednosti novouvedenih atributa Konstruktor ove klase je izmijenjen u odnosu na konstruktor klase “Obrok ” da omogući i inicijalizaciju dopunskih atributa. Metoda koja vraća ukupnu cijenu narudžbe modificirana je tako da vrati ukupnu cijenu koja uključuje kako cijenu obroka, tako i cijenu pića. Isto tako, modificirane su i metoda za ispis podataka o narudžbi, koja sada treba uključiti i dopunske informacije koje nisu postojale u klasi “Obrok ”, uključujući i informacije o ukupnoj cijeni, te metoda koja stvara dinamički kreiranu kopiju objekta.

Page 195: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

Klasa “Narudzbe ” predstavlja kolekciju narudžbi, izvedenu kao dinamički niz pokazivača na objekte tipa “Obrok ” ili “ ObrokSaPicem ”. Ova klasa sadrži konstruktor sa jednim parametrom, koji vrši odgovarajuću dinamičku alokaciju memorije, pri čemu parametar predstavlja maksimalan broj zahtjeva koji se mogu pohraniti. Klasa sadrži i odgovarajući destruktor, koji oslobađa memoriju koju je objekat tipa “Narudzbe ” zauzeo tokom svog života, te konstruktor kopije i preklopljeni operator dodjele koji omogućavaju bezbjedno kopiranje i međusobno dodjeljivanje objekata tipa “Narudzbe ” zasnovano na strategiji dubokog kopiranja. Od metoda, klasa “Narudzbe ” posjeduje četiri metode. Prve dvije metode “NaruciObrok ” i “ NaruciObrokSaPicem ” vrše kreiranje i dodavanje nove narudžbe, pri čemu se prva metoda odnosi na prostu narudžbu (obrok bez pića), dok se druga metoda odnosi na narudžbu obroka sa pićem. Parametri ovih metoda su isti kao i konstruktori klasa “Obrok ” odnosno “ObrokSaPicem ”. One kreiraju novu narudžbu (u skladu sa navedenim parametrima) i smještaju ga u kolekciju. Treća metoda “ObradiNaruzdbu ” nema parametara. Ona vrši ispis podataka o prvoj primljenoj narudžbi na ekran (tj. narudžbi koja najduže čeka na isporuku). Pored toga, ova metoda vrši brisanje obrađene narudžbe iz kolekcije, tako da će sljedeći poziv ove metode ispisati sljedeću naredbu po redu, i tako dalje, sve dok se ne obrade sve narudžbe. U slučaju da se ova metoda pozove kada je kolekcija prazna, metoda treba da baci izuzetak. Posljednja metoda koju posjeduje klasa “Narudzbe ” je metoda bez parametara “DaLiImaNarudzbi ” koja daje kao rezultat logičku vrijednost “true ” ako i samo ako objekat nad kojim je primijenjena predstavlja nepraznu kolekciju, a u suprotnom (tj. ako je kolekcija prazna) daje kao rezultat logičku vrijednost “false ”. Konačno, klasa “Narudzbe ” posjeduje i preklopljeni operator “[] ” koji kao rezultat daje ukupnu cijenu narudžbi koje je naručio student čije se ime navodi unutar uglastih zagrada (tj. zbir cijena svih narudžbi tog studenta). Ukoliko student sa navedenim imenom nije ništa naručio, ovaj operator kao rezultat daje nulu. Definirane klase treba demonstrirati u testnom programu koji obrađuje narudžbe na osnovu ulaznih podataka koji su pohranjeni u tekstualnim datotekama. Podaci su organizirani u dvije datoteke. Prva datoteka, nazvana “NARUDZBE.TXT”, predstavlja datoteku sa podacima samim narudžbama. Ova datoteka organizirana je tako da se za svaku narudžbu u prvom redu nalazi ime naručioca, u drugom redu naziv obroka, a u trećem redu naziv pića (treći red se ostavlja prazan ukoliko naručioc nije naručio piće). Narudžbe su u datoteci pohranjene u redoslijedu pristizanja. Na primjer, datoteka narudžbi bi mogla izgledati recimo ovako: Šaban Šauli ć Ćevapi u kajmaku Jogurt Zdravko Čoli ć Krompiruša Brus Li Ramadanovi ć Begova čorba Gusti sok Zdravko Čoli ć Čizburger Coca Cola

Druga datoteka, nazvana “CIJENE.TXT ”, predstavlja datoteku cijena. Ova datoteka organizirana je tako da se za svaki obrok ili piće u prvom redu nalazi naziv obroka ili pića, dok se u drugom redu nalazi cijena za navedeni obrok ili piće (u KM). Recimo, ova datoteka može izgledati recimo ovako: Burek 3 Sirnica 2.5 Zeljanica 2.5 Krompiruša

Page 196: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

2 Ćevapi 5 Ćevapi u kajmaku 6 Begova čorba 3 Jogurt 1 Coca Cola 2.5 Gusti sok 2.5 Fanta 2.5

Testni program bi trebao čitati podatke o naružbama iz tekstualne datoteke “NARUDZBE.TXT” uz konsultacije cjenovnika iz datoteke “CIJENE.TXT ” i smještati ih u kolekciju. Nakon što se pročitaju podatke o svim narudžbama, testni program treba da ispiše sve unesene narudžbe u redoslijedu pristizanja. Program bi trebao da presreće sve probleme koji bi se eventualno mogli pojaviti i da ispisuje odgovarajuće poruke upozorenja korisniku. Ovo uključuje recimo slučajeve kada ulazne datoteke sadrže podatke koji nisu u skladu sa očekivanjima, zatim slučajeve kada cjenovnik ne sadrži cijenu za neki naručeni obrok ili piće, itd. 3. Na Predavanju 13. razmotrena su dva primjera programa od kojih prvi kreira binarnu datoteku koja sadrži podatke o studentima nazvanu “STUDENTI.DAT”, dok drugi program iščitava sadržaj kreirane datoteke i obračunava prosjek studenata na osnovu podataka u datoteci. Dopunite ovu kolekciju programa trećim programom koji sortira sadržaj datoteke “STUDENTI.DAT” u opadajući poredak prema prosječnoj ocjeni, bez prethodnog učitavanja datoteke u niz (dakle, sve manipulacije treba raditi direktno nad datotekom). Za sortiranje koristite neki od naivnih algoritama sortiranja (npr. BubbleSort). U slučaju da dva studenta imaju isti prosjek, prije treba doći onaj čije ime dolazi prije po abecednom poretku. Neocijenjene studente tretirajte kao da imaju prosjek 0. SAVJET: Nakon što prvim programom kreirate testnu datoteku “STUDENTI.DAT”, obavezno napravite njenu rezervnu kopiju. Naime, dok Vam program ne proradi, vjerovatno ćete više puta uništiti sadržaj datoteke. Stoga, ukoliko ste napravili rezervnu kopiju, nećete morati svaki put kada uništite sadržaj datoteke pokretati ponovo program za kreiranje datoteke i unositi iznova podatke (što može biti veoma mučno). Umjesto toga, dovoljno je da kopirate rezervnu kopiju u datoteku “STUDENTI.DAT”. 2.OBROK

#include <iostream> #include <string> #include <fstream> #include "TestCurenja.h" using namespace std; class Obrok{ string naziv_obroka;

Page 197: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

double cijena; string narucioc; public: Obrok(string naziv_obroka, double cijena, string narucioc):naziv_obroka(naziv_obroka),cijena(cijena),narucioc(narucioc){} virtual string DajNazivObroka()const{return naziv_obroka;} virtual double DajCijenuObroka()const{return cijena;} virtual string DajNarucioca()const{return narucioc;} virtual void Ispisi()const{ cout<<"Narucilac->"<<narucioc<<endl<<"Obrok->"<<naziv_obroka<<endl<<"Cijena obroka->"<<cijena<<endl; } virtual double DajUkupnuCijenu()const{ return cijena;} virtual Obrok*DajKopiju()const{ return new Obrok(*this);} }; class ObrokSaPicem:public Obrok { string naziv_pica; double cijena_pica; public: ObrokSaPicem(string naziv_obroka, double cijena, string narucioc,string naziv_pica,double cijena_pica):Obrok(naziv_obroka, cijena, narucioc),naziv_pica(naziv_pica),cijena_pica(cijena_pica){} string DajNazivPica()const{return naziv_pica;} double DajCijenuPica()const{return cijena_pica;} double DajUkupnuCijenu()const{return DajCijenuObroka()+DajCijenuPica();} void Ispisi()const{ Obrok::Ispisi(); cout<<"Pice uz obrok->"<<naziv_pica<<endl<<"Cijena pica->"<<cijena_pica<<endl; } ObrokSaPicem*DajKopiju()const{return new ObrokSaPicem(*this);} }; class Narudzbe{ Obrok **narudzbe; int kapacitet; int broj_narudzbi; public: //konstruktor Narudzbe(int kapacitet):kapacitet(kapacitet),broj_narudzbi(0),narudzbe(new Obrok*[kapacitet]){}

Page 198: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

//destruktor ~Narudzbe(){for(int i=0;i<broj_narudzbi;i++)delete narudzbe[i]; delete[] narudzbe;} //konstruktor kopije Narudzbe(const Narudzbe &n) { narudzbe=new Obrok*[n.kapacitet]; for(int i=0;i<n.broj_narudzbi;i++)narudzbe[i]=n.narudzbe[i]->DajKopiju(); kapacitet=n.kapacitet; broj_narudzbi=n.broj_narudzbi; } Narudzbe&operator=(const Narudzbe&n) {for(int i=0;i<broj_narudzbi;i++)delete narudzbe[i]; delete[] narudzbe; narudzbe=new Obrok*[n.kapacitet]; for(int i=0;i<n.broj_narudzbi;i++)narudzbe[i]=n.narudzbe[i]->DajKopiju(); kapacitet=n.kapacitet; broj_narudzbi=n.broj_narudzbi; } void NaruciObrok(string naziv_obroka, double cijena, string narucioc){ if(broj_narudzbi>=kapacitet)throw "Kapaciteti za narudzbe su popunjeni."; else{ narudzbe[broj_narudzbi++]=new Obrok(naziv_obroka,cijena,narucioc);} } void NaruciObrokSPicem(string naziv_obroka, double cijena, string narucioc,string naziv_pica,double cijena_pica){ if(broj_narudzbi>=kapacitet)throw "Kapaciteti za narudzbe su popunjeni."; else{ narudzbe[broj_narudzbi++]=new ObrokSaPicem(naziv_obroka,cijena,narucioc,naziv_pica,cijena_pica); }} void ObradiNarudzbu(){ if(broj_narudzbi==0)throw "Nema narudzbi!"; narudzbe[0]->Ispisi(); delete narudzbe[0]; for(int i=1;i<broj_narudzbi;i++) for(int j=0;j<broj_narudzbi-1;j++) narudzbe[j]=narudzbe[i]; broj_narudzbi--; } bool DaLiImaNarudzbi()const{ if(broj_narudzbi!=0)return true;

Page 199: Izrađeni tutorijali i zadace (2011-2012)-TEHNIKE PROGRAMIRANJA

return false;} double operator[](string naruciocpom){ double suma(0); for(int i=0;i<broj_narudzbi; i++) { if(naruciocpom==narudzbe[i]->DajNarucioca())suma+=narudzbe[i]->DajUkupnuCijenu(); } return suma; } }; int main() { ifstream narudzbe("Narudzbe.txt"); ifstream cjenovnij("Cijene.txt"); string ime, nazivJela,nazivSoka,nazivObroka; double cijena; int broj_narudzbi(0); for(;;) { getline(narudzbe,ime); getline(narudzbe,nazivJela); getline(narudzbe,nazivSoka); if(!narudzbe)break; broj_narudzbi++; for(;;){ getline(cjenovnij,nazivObroka); cjenovnij.ignore(100,'\n'); cjenovnij>>cijena; if(cjenovnij.fail()){cout<<"Fali cijena u cjenovniku!";break;} if(!cjenovnij)break; if(nazivObroka==nazivJela) { if(nazivSoka!=string()) cout<<ime<<endl<<nazivJela<<endl<<nazivSoka<<endl;} return 0; }}}