You are on page 1of 199

Izraeni tutorijali(2011/2012), neki zadaci sa parcijalnih

ispita, zadace(2011/2012) iz predmeta TEHNIKE


PROGRAMIRANJA
Zadaci su raeni tokom cijelog semestra dok je trajao kurs, tako da izrada nekih zadataka s
prvih tutorijala bi moda mogla biti i jednostavnije izvedena, ali moda je nain razmiljanja s
raspoloivim znanjem do tog tutorijala pogodniji.
Greke su mogue i zadaci sa zadaa ne prolaze 100% svaki autotest, ali su bili dovoljno
dobri za 80% bodova.

Izrada zadataka: Tajma Kovaevi


Eman Jaarevi

Zadaci za Tutorial 1.
1. Napiite program koji e na ekranu ispisati vae line podatke u sljedeem obliku:
Vae ime i prezime
------------------ ime podvui crticama
ostaviti jedan prazan red
Datum roenja
Smjer studija
Grad

Program napiite u C++ stilu, koristei biblioteku iostream i objekat izlaznog toka cout.
2. Napiite program koji izraunava koliko je keramikih ploica potrebno za poploavanje bazena
ije se dimenzije u metrima unose sa tastature. Dimenzije ploica u centimetrima se takoer
unose sa tastature. Program nakon pokretanja treba da na ekranu proizvede dijalog poput
sljedeeg (naravno, brojevi koje korisnik zadaje odabrani su proizvoljno):
Unesi dimenzije bazena (axbxc) u metrima: 5 15 3
Unesi dimenzije ploice (axb) u centimetrima: 10 10
Za poploavanje bazena dimenzija 5x15x3 m sa ploicama dimenzija 10x10 cm
potrebno je 19500 ploica.

Preutno pretpostavite da su dimenzije zadane tako da je poploavanje uvijek izvodivo sa


cijelim brojem ploica. Za unos podataka i ispis rezultata koristite objekte cin i cout iz
biblioteke iostream.
3. Napiite program koji trai 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 duina ma koje dvije stranice vei od duine tree stranice.
Ukoliko uneseni brojevi mogu predstavljati duine stranica trougla, treba izraunati njegov
najvei ugao i ispisati njegovu vrijednost u stepenima, minutama i sekundama. Za raunanje
ugla koristite kosinusnu teoremu prema kojoj je c2 = a2 + b2 2 a b cos (i analogno tome za
preostale kombinacije stranica i uglova). Raunajte da 1 radijan ima 180/ stepeni, dok
vrijednost moete raunati po formuli = 4 arctg 1. Ukoliko uneseni brojevi ne mogu
predstavljati duine stranica trougla, treba ispisati odgovarajui komentar. Dijalozi koje formira
program trebaju izgledati poput sljedeih:
Unesite tri broja: 6 4 3
Najvei 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 odgovarajua raunanja funkcije iz biblioteke cmath.

4. Napiite program koji trai da se sa tastature unese prirodan broj n. U sluaju da korisnik unese
neto to nije prirodan broj (to ukljuuje i situaciju kada uneseni podatak uope nije broj), treba
ispisati poruku upozorenja, i ponoviti unos. Ukoliko je unos ispravan, program treba da izrauna
i ispie 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 trai 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()
{

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()
{

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);

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');

}
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;
}

Zadaci za Tutorial 2.
1. Napiite program koji e prvo traiti 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
ukljuivo. Tablica bi trebala da izgleda poput tablice na sljedeoj 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 nee biti vei od 100.
2. U teoriji elektrinih 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 moe biti i
negativan. Ukoliko imamo paralelni spoj n elemenata ije su impedanse Z1, Z2, ... Zn, ukupna
impedansa paralelne veze Z rauna se kao Z = 1 / (1 / Z1 + 1 / Z2 + ... + 1 / Zn). Drugim rijeima,
situacija je slina paralelnom spajanju otpornika, osim to se ovdje radi sa kompleksnim
impedansama. Napiite program u kojem se od korisnika trai 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 rauna i ispisuje aktivni i reaktivni otpor paralelne
veze svih n elemenata. Dijalog izmeu programa i korisnika treba da izgleda poput sljedeeg:
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 raunajte 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 eik. Program na kraju treba prikazati prividni otpor i fazni pomak za itavu
paralelnu vezu. Fazni pomak treba zadavati ispisivati u stepenima. Uputa: trebae 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. Napiite funkciju koja kao parametar prima vektor realnih brojeva. Funkcija treba da ispita da li
elementi vektora ine slijed koji se periodino ponavlja ili ne. Na primjer, za vektor iji su
elementi 5, 9, 7, 2, 5, 9, 7, 2, 5, 9, 7 uoavamo da njegovi elementi ine slijed koji se periodino
ponavlja sa duinom perioda 4. Ukoliko elementi vektora ine periodian slijed, funkcija treba
da vrati kao rezultat duinu 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 oznaava kraj unosa (tu nulu
ne treba smjestiti u vektor). Nakon zavretka unosa, program poziva napisanu funkciju sa ciljem
da utvrdi da li se elementi periodino ponavljaju ili ne, nakon ega ispisuje odgovarajui

komentar na ekranu (informaciju o duini perioda, ili da elementi ne ine periodian slijed).
Napomenimo da nije unaprijed poznato koliko e korisnik unijeti elemenata prije nego to unese
nulu kao oznaku zavretka 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>

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;

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;

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];

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

Zadaci za Tutorial 3.
1. Napiite program koji trai da se prvo unese prirodan broj n, a nakon toga elementi vektora
a koji ima n cjelobrojnih elemenata, za koje emo preutno pretpostaviti da su svi prirodni
brojevi, tj. vei 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 prepie sve proste brojeve iz
vektora a (tj. one djeljive samo sa 1 i sa samim sobom), a u vektor c sve sloene brojeve iz
vektora a (tj. one koje imaju vie od dva djelioca). Konano, program treba da u jednom redu
ispie elemente vektora b, a u drugom redu elemente vektora c. Brojevi trebaju biti
meusobno 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 sloenim. Posebno testirajte sluajeve 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 vektr sa cjelobrojnim elementima,
popunjava je tablicom mnoenja pri emu mnoenici u redovima tablice idu od 1 do m a
mnoitelji u kolonama tablice od 1 do n, i na kraju, vraa tako kreiranu matricu kao rezultat. Na
primjer, za m = 3 i n = 5 kreirana matrica treba da ima elemente kako je prikazano ispod:
12345
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 mnoenja kako je opisano gore, i
na kraju ispisuje kreiranu matricu uredno poravnatu na nain slian kako je prikazano gore. Za
ispis svakog elementa matrice zauzmite po 5 mjesta (pomou manipulatora setw).
4. Napiite 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, trei 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 sljedeeg:
1
1
1
1
1
1
1

1
2
3
4
5
6

1
3 1
6 4 1
10 10 5 1
15 20 15 6 1

Pri tome, elemente Pascalovog trougla nije dozvoljeno raunati preko binomnih koeficijenata,

ve treba koristiti injenicu da je svaki element Pascalovog trougla jednak zbiru elemenata koji
se nalaze tano iznad njega, i njegovog susjeda sa lijeve strane.
2
5. Napiite funkciju sa dva parametra, od kojih je prvi tipa string, a drugi cjelobrojnog tipa.
Prvi parametar predstavlja neku reenicu, a drugi parametar redni broj rijei unutar te reenice.
Funkcija treba da izdvoji tu rije iz reenice, 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 nita), i iza kojeg eventualno slijedi razmak (ili nita). Tako se, na
primjer, u tekstu Kia pada.Trava raste slijed znakova pada.Trava tretira kao jedna rije
(druga po redu), jer iza take nema razmaka (ovakav tretman vrijedi i u tekst procesorima poput
Microsoft Word-a). Obratite panju da rijei mogu biti razdvojene sa vie uzastopnih razmaka,
kao i da na poetku i kraju teksta moe, ali i ne mora biti razmaka. Ukoliko je drugi parametar
manji od 1 ili vei od broja rijei u reenici, funkcija treba baciti izuzetak.
Napisanu funkciju demonstrirajte u testnom programu u kojem se za reenicu unesenu sa
tastature i prirodan broj n ispisuje n-ta rije te reenice (pozivom napisane funkcije). U testnom
programu obavezno predvidite hvatanje izuzetaka koji mogu biti baeni 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++)

{
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;

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;}

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;

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;
}

Zadaci za Tutorial 4.
1. Napiite program koji trai od korisnika da unese spisak rijei (broj rijei se prethodno unosi sa
tastature), a zatim ispisuje na ekran prvu i poslednju rije iz spiska po abecednom poretku, kao i
popis svih unesenih rijei, ali bez ispisivanja duplikata (tj. bez ispisivanja rijei koje su se ve
jednom ispisale). Program realizirajte koritenjem vektora stringova, odnosno vektora iji su
elementi tipa string. Pri tome, nije dozvoljeno sortirati sadraj vektora.
2. Napiite funkciju Cifre koja treba da ima 3 parametra n, c min i c max. Funkcija
treba da pronae najmanju i najveu cifru u parametru n (koji predstavlja neki prirodan broj), i
da smjesti pronaene 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 najvea cifra u broju 37232645. Funkcija ne smije koristiti nikakve
pomone nizove ili vektore (samo individualne promjenljive). Napiite i kratki testni program u
kojem ete demonstrirati napisanu funkciju.
3. Napiite funkciju IzvrniString sa jednim parametrom tipa string. Funkcija treba da
ispremjeta elemente stringa tako da prvi znak postane posljednji, a posljednji prvi. Na primjer,
ukoliko se u glavnom programu izvri 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 vri premjetanje u mjestu, odnosno da ne koristi nikakav pomoni string osim stringa
koji je prenesen kao parametar (uputa: razmijenite prvi znak sa posljednjim, drugi sa
pretposljednjim, itd.). Napiite i kratki glavni program u kojoj ete demonstrirati napisanu
funkciju na reenici koja se unosi sa tastature. Oprez: funkcija izvrni ne smije sama po sebi nita
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. Napiite generiku funkciju UnosBroja sa tri parametra. Funkcija treba da omogui
pouzdano unoenje brojeva u program, uz potpunu kontrolu greaka 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 sluaju da unos nije ispravan. Trei parametar je referenca na
proizvoljni numeriki tip, a predstavlja promjenljivu u koju e se smjestiti uneseni broj. Na
primjer, funkcija se moe pozvati na sljedei nain:
UnosBroja("Unesi prvi broj: ", "Neispravan unos!\n", prvi_broj);

Funkcija treba da trai unos od korisnika sve dok unos ne bude ispravan. Napisanu funkciju
demonstrirajte u testnom programu koji od korisnika trai da unese realni broj x i cijeli broj n, a
zatim rauna i ispisuje vrijednost stepena xn.
5. Napiite generiku 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 rijeima, treba
formirati presjek skupova iji su elementi pohranjeni u vektorima v1 i v2). Pored toga, u
vektoru koji je vraen kao rezultat iz funkcije svi elementi treba da budu razliiti (odnosno,
elemente koji se ponavljaju ne treba prepisivati vie 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).

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;

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;
}

Zadaci za Tutorial 5.
1. Napiite program koji od korisnika trai da sa tastature unese reenicu, a koji e zatim ispisati
unesenu reenicu bez prve rijei te reenice. Unesena reenica se smjeta u klasini niz znakova
(dakle, ne u promjenljivu tipa string). Za realizaciju zadatka koristiti iskljuivo pokazivaku
aritmetiku. Nije dozvoljena upotreba funkcija iz biblioteka cstring niti string, kao ni
upotreba indeksiranja (ukljuujui i njegovu trivijalnu simulaciju koja podrazumijeva pisanje
*(a+n) umjesto a[n]).
2. Napiite funkciju sa jednim parametrom n, koja dinamiki 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 vraa kao
rezultat pokaziva na prvi element tako alociranog niza. U sluaju da je n 0, funkcija treba da
baci tekst Broj elemenata mora biti pozitivan kao izuzetak, a u sluaju 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 traenog niza, koji se potom ispisuje na ekran, i na kraju se vri oslobaanje prostora
koji je zauzeo niz. Pored toga, u glavnom programu treba predvidjeti hvatanje svih izuzetaka
koji bi funkcija eventualno mogla baciti.
3. Napiite generiku funkciju iji je parametar vektor elemenata proizvoljnog tipa. Funkcija prvo
treba da dinamiki kreira niz iji su elementi istog tipa kao i zadani vektor i koji sadri 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. Napiite i mali testni program
u kojem ete demonstrirati kako se upotrebljava napisana funkcija na vektoru realnih brojeva iji
se elementi unose sa tastature.
4. Napiite generiku funkciju koja kao svoj parametar prima dvodimenzionalnu strukturu (recimo
matricu, ali pri emu broj elemenata u svakom redu ne mora nuno biti isti) predstavljenu kao
vektor vektr iji su elementi proizvoljnog tipa. Funkcija prvo treba da dinamiki alocira
prostor za dvodimenzionalnu strukturu identinog oblika kao i parametar, zatim da u nju prepie
elemente dvodimenzionalne strukture predstavljene parametrom i, konano, da kao rezultat vrati
dvojni pokaziva preko kojeg se moe izvriti pristup elementima ove strukture. U sluaju da
doe do problema sa alokacijom memorije, funkcija treba baciti izuzetak. Pri tome, ni u kom
sluaju ne smije doi do curenja memorije. Napisanu funkciju testirati u testnom programu koji
sa tastature unosi elemente matrice formata 3 3 organizirane kao vektor vektr, a nakon toga
poziva napisanu funkciju sa ciljem kreiranja odgovarajue dinamike matrice i, konano,
ispisuje elemente tako kreirane dinamike matrice na ekran i oslobaa zauzetu memoriju. U
testnom programu predvidjeti i eventualno hvatanje baenih 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;

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
{

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: ";

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 pomou kojih je mogue izraunati priblinu vrijednost integrala neke
funkcije f(x) na intervalu (a, b). Jedan od najjednostavnijih ali ujedno i najmanje tanih metoda
je tzv. trapezno ili Eulerovo pravilo, prema kojem je

gdje je n broj podintervala na koji dijelimo interval (a, b). Vei broj podintervala daje i veu
tanost, ali do odreene granice. Napiite funkciju TrapeznoPravilo koja prima kao
parametre f, a, b i n ( f je funkcija iji se integral rauna) a koja kao rezultat daje priblinu
vrijednost integrala raunatu pomou 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 izvrite za razliite vrijednosti n i uporedite rezultate
sa tanim rezultatima. Utvrdite kolike su vrijednosti za n bile potrebne da se dobije rezultat taan
na 5 decimala za sva tri primjera.
2a. Napiite program koji trai od korisnika da unese niz reenica, pri emu se broj reenica
prethodno unosi sa tastature. Za svaku unesenu reenicu dinamiki alocirajte prostor, uz voenje
evidencije o adresi svake alocirane reenice u dinamikom nizu pokazivaa na poetke svake od
reenica. Nakon toga, treba ispisati unesene reenice sortirane u abecedni poredak (tanije
reeno, u rastui poredak po ASCII kodovima). Sortiranje obavite runo, nekim od jednostavnih
postupaka za sortiranje koji Vam je poznat (npr. BubbleSort, SelectionSort, itd.). Drugim
rijeima, nemojte koristiti gotove funkcije za sortiranje, poput funkcije sort iz biblioteke
algorithm.
2b. Izmijenite prethodni program, ali tako to ete umjesto runog sortiranja koristiti funkciju
sort iz biblioteke algorithm, uz pogodno definiranu funkciju kriterija.
3. Napiite generiku funkciju Razmjeni koja prihvata iste parametre i obavlja isti zadatak kao
funkcija swap ranges iz biblioteke algorithm. Funkciju treba realizirati iskljuivo
koritenjem pokazivake aritmetike, bez koritenja indeksiranja i njegove trivijalne simulacije
(tj. pisanja *(p+i) umjesto p[i]). Napiite 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. Koristei odgovarajue funkcije iz biblioteke algorithm, napiite program koji e za niz
cijelih brojeva unesenih sa tastature ispisati:
najvei 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 uope dozvoljeno koristiti petlje (osim za unos elemenata niza), ve
sve manipulacije treba ostvariti iskljuivo pozivima funkcija iz biblioteke algorithm.

4b. Izmijenite prethodni program tako to ete umjesto niza koristiti vektor.
5. Napiite 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 pronaen unutar niza. Koristite binarnu pretragu i odgovarajue funkcije iz
biblioteke algorithm.

Zadaci za Tutorial 7.
1. Definirajte strukturu Vrijeme koja sadri tri polja sati, minute i sekunde, i koja
predstavlja tekue vrijeme u toku dana, izraenu u satima, minutama i sekundama. Zatim
definirajte funkciju IspisiVrijeme koja ispisuje vrijeme proslijeeno kao parametar u
funkciju u obliku hh:mm:ss (tj. sati, minute i sekunde se ispisuju kao dvocifreni brojevi,
eventualno sa vodeim nulama), kao i funkciju SaberiVrijeme koja prima dva vremena kao
parametre, i vraa kao rezultat tree vrijeme koje nastaje sabiranjem vremena koja su
proslijeena kao parametri (npr. sabiranjem 3h 34min 52sek i 4h 42min 20sek treba da se dobije
vrijeme 8h 17min 12sek). Konano, napravite mali testni program u kojem ete testirati napisane
funkcije.
2. Prepravite program ucenici.cpp priloen uz Predavanje 7, tako da se umjesto vektora
uenika koristi dinamiki alociran niz uenika (biblioteku i tip vector nije dozvoljeno
koristiti). Upute za ovu prepravku date su na predavanjima.
3. Prepravite program ucenici_pok.cpp priloen uz Predavanje 7, tako da se umjesto vektora
pokazivaa na uenike koristi dinamiki alociran niz pokazivaa na uenike uenika (biblioteku
i tip vector nije dozvoljeno koristiti). Upute za ovu prepravku date su na predavanjima.
4. Definirajte strukturu Cvor koja sadri 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 ispie koliko ima elemenata u listi koji su vei od
aritmetike sredine svih unesenih elemenata (potrebna su zapravo dva prolaza: prvi za raunanje
aritmetike sredine, i drugi za brojanje elemenata sa traenim 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;

}
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);

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";

}
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);

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);
//dinamiki niz pokazivaa na strukture tipa Ucenik,

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;

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)
{

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;

}
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++;
}

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++;

}
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 omogue neovisnu izmjenu pojedinanih koordinata
vektora. Napiite 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
sljedei interfejs:
void Postavi(int sati, int minute, int sekunde);
void Sljedei();
void Prethodni();
void PomjeriZa(int pomak);
int DajSate() const;
int DajMinute() const;
int DajSekunde() const;
void Ispisi() const;
Metoda Postavi omoguava postavljanje sata na zadani iznos sati, minuta i sekundi. Ova
metoda baca izuzetak ukoliko se proslijede neispravni parametri. Metoda Sljedeci treba da

povea vrijeme zapameno u satu za 1 sekundu (npr. ukoliko je tekue vrijeme 12:48:59,
nakon poziva ove metode vrijeme treba da postane 12:49:00). Slino, metoda Prethodni
treba da smanji vrijeme zapameno u satu za 1 sekundu, dok metoda PomjeriZa predstavlja
generalizaciju prethodne dvije metode tako to vri pomak tekueg vremena za broj sekundi koji
je zadan parametrom pomak (pomjeranje je unazad ukoliko se proslijedi negativna vrijednost
kao parametar). Metoda Ispisi treba da ispie stanje sata u obliku hh : mm: ss. Metode
DajSate, DajMinute i DajSekunde vraaju trenutni broj sati, minuta i sekundi u
tekuem vremenu. Kao atribute klase uzmite trenutni broj sati, minuta i sekundi, koje ete

definirati kao privatne atribute. Obavezno napiite 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 sluaj.
4. Definirajte i implementirajte klasu Sat koja ima potpuno isti interfejs i potpuno isto ponaanje
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
kae 12015 sekundi). Mada e ovo traiti 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 moda metoda Ispisi zakomplicirati), pokaite 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
{

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;
}
};

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;

// 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)
{

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(){

....
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;

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;

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();

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();

}
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 Vaim jezikim opredjeljenjem)
koja omoguava rad sa uglovima (kutovima) u ravni. Klasa treba da ima sljedei 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

vraa vrijednost ugla u radijanima. Metoda OcitajKlasicneJedinice oitava vrijednost


ugla u stepenima, minutama i sekundama i smjeta oitane vrijednosti u odgovarajue parametre
metode. Metode DajStepene, DajMinute i DajSekunde omoguavaju da se istim
ovim informacijama pristupi neovisno, a ne iskljuivo 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 vraa kao rezultat tako
modificiran ugao. Metoda PomnoziSa mnoi ugao nad kojim je primijenjena sa brojem koji
je zadan parametrom i usput vraa kao rezultat tako modificiran ugao. Obje ove metode trebaju
obezbijediti da nakon izvrene operacije rezultat bude reduciran na opseg 0 2 (0 360 ).
Konano, prijateljske funkcije ZbirUglova i ProduktUglaSaBrojem vraaju 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). Napiite 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 sadre broj stepeni,
minuta i sekundi koje ine ugao. Iako e ova izmjena traiti promjenu implementacije gotovo
svih metoda klase, uvjerite se da e nakon te izmjene testni program koji koristi napisanu klasu i
dalje raditi posve identino, 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; }

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 {

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){

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;

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;
}

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 sadre redom
naziv tima (do 20 znakova), broj odigranih utakmica, broj pobjeda, broj nerijeenih utakmica,
broj poraza, ukupan broj datih i primljenih golova, kao i broj poena za razmatrani tim. Atribut
ime treba izvesti kao klasini niz znakova. Klasa treba da ima sljedei 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) aurira
ne samo atribute koje broje golove, nego i atribute koji broje odigrane utakmice, broj pobjeda,
poraza i nerijeenih utakmica, kao i broj bodova. Pri tome se za pobjedu dodjeljuju 3 boda, za
nerijeen rezultat 1 bod, dok se za poraz ne dodjeljuju bodovi. Metode DajImeTima,
DajBrojPoena i DajGolRazliku treba da vrate respektivno ime tima (tanije, pokaziva
na prvi znak imena), broj poena, kao i gol razliku (tj. razliku izmeu ukupnog broja datih i
primljenih golova) za posmatrani tim (ove metode implementirati unutar deklaracije klase).
Konano, metoda IspisiPodatke treba da ispie na ekran sve podatke o timu u jednom
redu, i to sljedeim redom: ime tima, broj utakmica, broj pobjeda, broj nerijeenih 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

brojne podatke prostor od 4 znaka na ekranu, pri emu ispis svakog brojanog podatka treba biti
poravnat udesno unutar predvienog prostora. Napiite i kratki testni program u kojem ete
demonstrirati napisanu klasu.
2. Napiite 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 sluiti za pristup dinamiki 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 izvri dinamiku alokaciju memorije za prihvatanje onoliko timova koliko
je navedeno parametrom, dok destruktor treba da izvri oslobaanje svih resursa koje je klasa
Liga alocirala tokom svog rada. Metoda DodajNoviTim kreira tim sa navedenim imenom
(tj. dinamiki kreira objekat tipa Tim) i upisuje ga na prvo slobodno mjesto u ligu (tj. upisuje
pokaziva na njega na odgovarajue mjesto u nizu pokazivaa na objekte tipa Tim). Pri tome
se, naravno, broj timova u ligi poveava za jedinicu. Metoda ne smije da dozvoli upis vie
timova od maksimalno dozvoljenog broja timova. U metodi RegistrirajUtakmicu prva
dva parametra predstavljaju imena timova koji su odigrali utakmicu, dok su trei i etvrti
parametar broj golova koji su dali prvi i drugi tim respektivno. Ova metoda treba da aurira
rezultate u tabeli za oba tima, odnosno da baci izuzetak ukoliko timovi sa navedenim imenima
ne postoje u tabeli. Konano, metoda IspisiTabelu treba da ispie tabelu lige sortiranu u
opadajuem poretku po broju bodova. Ukoliko dva tima imaju isti broj poena, tada u tabeli prvo
dolazi tim sa veom gol razlikom. Sortiranje vrite pozivom funkcije sort, uz pogodno
definiranu funkciju kriterija, koju trebate izvesti kao privatnu statiku funkciju lanicu klase.
Ispis treba vriti pozivom metode IspisiPodatke iz klase Tim, tako da bi tabela trebala
da ima izgled poput sljedeeg:
elik 18 11 5 1 34 10 38
Jedinstvo 18 9 4 5 33 20 31
eljezniar 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 meusobno 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 baenih izuzetaka.
3. Izmijenite klasu Liga razvijenu u prethodnom zadatku, tako to e se za evidenciju pokazivaa
na dinamiki alocirane objekte tipa Tim umjesto dinamiki alociranog niza pokazivaa
koristiti vektor iji su elementi pokazivai na objekte tipa Tim. Taj vektor e, naravno, biti
privatni atribut klase (nazvaemo ga isto timovi, jer to trai najmanju prepravku klase).
Privatni atributi broj_timova i max_br_timova vie nee biti potrebni. Zaista, broj
timova se moe saznati testiranjem trenutne veliine vektora, dok maksimalan broj timova vie
nije potrebno zadavati, s obzirom da vektor moe u toku rada po volji poveavati svoju veliinu
(ogranieni smo iskljuivo koliinom raspoloive memorije). Jedina izmjena u interfejsu klase
bie u tome to konstruktoru vie nee biti potreban parametar (zahvaljujui fleksibilnosti
vektora, u ligu e se moi dodati onoliko timova koliko elimo, bez potrebe da unaprijed
specificiramo njihov maksimalan broj). Naravno, destruktor e i dalje biti potreban (da oslobodi

sve dinamiki alocirane timove nakon to objekat tipa Liga prestane postojati). to se tie
semantikih 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 ogranienje na maksimalan broj timova vie ne postoji (osim ogranienja uvjetovanih
koliinom raspoloive memorije). Svi ostali aspekti funkcioniranja klase Liga ostaju
neizmijenjeni.
NAPOMENA: Mali broj studenata e stii uraditi sva tri zadatka za vrijeme koje je predvieno za
tutorijal. Meutim, svim studentima se toplo savjetuje da dovre samostalno one zadatke koje nisu
stigli
uraditi za vrijeme tutorijala, s obzirom da je razumijevanje ovog tipa zadataka od vitalne vanosti 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!";

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!";

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();
};

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();

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>

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

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

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!";

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);

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() moemo
prosto pisati v1 += v2, v3 = v1 + v2 i cout << v1. Pri tome se podrazumijeva da ete
odgovarajue izmjene izvriti 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 podrati 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 drugaijih 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. Sreom,

ovakvo ponaanje se moe izmijeniti koritenjem preklapanja operatora. Napiite operatorsku


funkciju za operator << koji e omoguiti da se prilikom ispisa konstanti, promjenljivih i
izraza tipa Dani umjesto brojane vrijednosti dobijene konverzijom ispisuje tekst koji
odgovara njihovom znaenju. Testirajte napisanu funkciju u testnom programu koji sadri petlju
for(Dani d = Ponedjeljak; d <= Nedjelja; d++) cout << d << endl;

Takva petlja treba da zaista ispie imena dana u sedmici, a ne brojeve od 0 do 6.


4. Mada je ve odavno u itavom svijetu izvrena standardizacija mjernih jedinica za razne
fizikalne veliine (SI sistem), Sjedinjene Amerike Drave se uporno opiru uvoenju ovih
jedinica, nego u internoj upotrebi i dalje koriste svoje vlastite mjerne jedinice, koje su, uz neke
izmjene, uglavnom naslijeene iz Britanskog kraljevstva (interesantno je da su jo jedine dvije
drave na svijetu pored SAD-a koje se opiru uvoenju SI sistema Liberija i Mjanmar, biva
Burma). Tako se, u SAD-u, duine uglavnom izraavaju u inima (inch), stopama (feet),
jardima (yard) i miljama (mile). Tako, jedna stopa ima 12 ina, jedan jard ima 3 stope, dok
jedna milja ima 1760 jardi (nie veze, to bi rekli u Hercegovini). Veza sa SI sistemom lako se
izvodi znajui da jedan in iznosi 2,54 centimetra. Napravite klasu koja omoguava raunanje sa
amerikim mjerama za duinu, kao i pretvorbe izmeu amerikog i standardnog sistema
mjerenja duine. Interfejs klase treba da sadri sljedee elemente:
Konstruktor sa tri cjelobrojna parametra koja omoguava zadavanje duine u jardima,
stopama i inima (milje emo ovdje zanemariti), npr. 9 jardi, 2 stope i 7 ina. Vrijednosti
ovih parametara ne moraju biti ograniene (npr. broj ina ne mora biti u opsegu od 0 do 11).
Stoga je, recimo, sasvim legalno zadati 5 jardi, 7 stopa i 14 ina, ali treba imati na umu da je

to isto to i 7 jardi, 2 stope i 2 ina. Kako su parametri cjelobrojni, smatraemo da nas ne


zanimaju dijelovi ina, odnosno sve duine uvijek e imati cijeli broj ina.
Konstruktor sa jednim realnim parametrom, koji omoguava da se duina zada u metrima.
Unutar ovog konstruktora potrebno je izvriti pretvorbu metrikih u amerike mjerne
jedinice. Rezultat pretvorbe treba zaokruiti na cijeli broj ina.
2
Metodu sa tri cjelobrojna parametra koja oitava broj jardi, stopa i ina pohranjen u objektu i
smjeta ih respektivno u tri navedena parametra. Pri tome, oitane vrijednosti moraju biti
normalizirane u smislu da broj ina uvijek mora biti u opsegu od 0 11 a broj stopa u opsegu
0 2.
Metodu koja kao rezultat daje pohranjenu duinu u metrima (kao realan broj).
Preklopljeni operator + koji daje kao rezultat novu duinu koja je jednaka zbiru duina koje
su zadane kao operandi.
Preklopljeni operator += koji obezbjeuje da izraz oblika X += Y uvijek ima isto
znaenje kao i izraz X = X + Y .
Preklopljeni operator ++ koji poveava duinu pohranjenu u objektu za 1 in. Potrebno je
podrati i prefiksnu i postfiksnu verziju ovog operatora.
Preklopljeni operator * koji omoguava mnoenje duine sa realnim brojem odnosno
mnoenje realnog broja sa duinom (mnoenje dvije duine ne treba podrati, jer rezultat
takvog mnoenja nije duina, nego povrina), dajui novu duinu kao rezultat. Rezultat se
zaokruuje na cijeli broj ina.
Preklopljeni operator / koji dijeli dvije duine i daje realni broj kao rezultat (jednak odnosu
duina koje se dijele).
Preklopljeni operator << koji omoguava ispis duina na izlazni tok u formatu
a yd b ft c in (recimo 9 yd 2 ft 7 in).
Obavezno napiite i kratki testni program u kojem ete testirati napisanu klasu. U ovom zadatku
namjerno nije reeno ta su atributi klase koju treba razviti. U naelu, za atribute moete uzeti
ta god hoete to Vam treba da ova klasa radi ono to treba da radi (to i jeste poenta
enkapsulacije i skrivanja informacija). Meutim, sama implementacija klase e bitno ovisiti od
toga ta uzmete da su atributi. U zavisnosti od izbora, implementacija moe biti izuzetno
jednostavna, ali i prilino komplicirana. Zato nemojte biti brzopleti i dobro razmislite ta uzeti
za atribute. Rjeenje koje prvo pada na pamet nije nuno i najpametnije rjeenje. Stoga, ukoliko
Vam se rjeavanje ovog zadatka primijetno zakomplicira, znajte da je do Vas.
NAPOMENA: Mnogi studenti nee uspjeti uraditi sva etiri zadatka za vrijeme koje je predvieno za
tutorijal. Meutim, svim studentima se toplo savjetuje da dovre samostalno one zadatke koje nisu
stigli
uraditi za vrijeme tutorijala, s obzirom da je razumijevanje ovog tipa zadataka od vitalne vanosti 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) {}

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;

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;

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<<")";

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){

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 dua od dvije naredbe obavezno implementirajte
izvan klase. Takoer, sve metode koje su inspektori obavezno deklarirajte kao takve.

Zadatak 1a (7,5 poena):


U kompjuterskoj grafici veoma se esto javlja potreba za radom sa matricama, pri emu te matrice
nikada nemaju format vei od 4 4 (mogui su i manji formati). Stoga je, radi lakeg rada sa ovakvim
matricama, veoma praktino razviti posebnu klasu, koju moemo 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 ograniene na 4 4, nema potrebe za koritenjem dinamike
alokacije memorije, niti fleksibilnih tipova podataka kao to su vektori (odnosno vektori vektr).
Stoga elemente matrice uvajte u atributu koji je obini dvodimenzionalni niz realnih brojeva formata
4 4. Meutim, kako format matrice moe biti i manji od 4 4, predvidite i dva atributa koji uvaju
stvarni broj redova i kolona matrice (naravno, u sluaju kada je format manji od 4 4, neki elementi
dvodimenzionalnog niza pohranjenog unutar odgovarajueg atributa bie neiskoriteni). Pored
navedenih atributa, klasa GMatrica treba da sadri i sljedee:
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 sluaju 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 odgovarajuim vrijednostima iz dvodimenzionalnog niza koji je zadan kao parametar.
Glavna uloga ovog konstruktora je da omogui 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,
odgovarajua operatorska funkcija ne treba da bude funkcija lanica. Napomena: da utedite 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 mnoiti samo ukoliko je broj kolona prve matrice jednak broju redova
druge matrice. U suprotnom, treba baciti izuzetak. Odgovarajue 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
odgovarajuim elementima j-te kolone matrice B.
Preklopljeni operator += koji obezbjeuje da izraz oblika X += Y uvijek ima isto znaenje kao
i izraz X = X + Y . Odgovarajua operatorska funkcija treba da bude funkcija lanica.
Preklopljene operatore == i != koji testiraju da li su dvije matrice jednake odnosno razliite.
Preklopljeni operator () koji omoguava pristup elementu u i-tom redu i j-toj koloni matrice
navoenjem i i j razdvojenih zarezom unutar zagrada (npr. a(2, 3) predstavlja element matrice
a u drugom redu i treoj koloni). Indeksi redova i kolona treba da poinju od jedinice, kako je to
uobiajeno u matematici notaciji. Ukoliko indeksi nisu legalni, treba baciti izuzetak. Operator treba
da vrati referencu na odgovarajui element da bi se omoguilo koritenje ove notacije sa lijeve
strane znaka jednakosti, osim u sluaju da se ovaj operator primijeni na konstantnu matricu (u tom
sluaju, ne treba vraati referencu na element, nego njegovu kopiju).
Preklopljeni operator << koji omoguava 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 sadraj matrice u binarnu datoteku ije se ime navodi kao parametar, odnosno
obnavljaju sadraj matrice iz datoteke ije se ime navodi kao parametar.
Zadatak 1b (1,5 poen):
Opiite ta bi se tano izmijenilo u realizaciji prethodnog zadatka ukoliko bi se trailo da klasa
GMatrica bude generika, tako da se tip elemenata matrice moe zadavati (npr. da se podre

matrice sa cjelobrojnim ili kompleksnim elementima). Posebno istaknite kako bi se izveo preklopljeni
operator + i operatori slini njemu.
Zadatak 2a (9,5 poena):
Za voenje evidencije podataka o robi u nekom skladitu potrebno je razviti kontejnersku klasu
nazvanu
Skladiste. U skladitu se roba nalazi pohranjena u sanducima (za vrste predmete) i u buradima
(za
tenosti). Sanduci i burad se modeliraju redom pomou klasa Sanduk odnosno Bure. Sanduk je
opisan svojom teinom, nazivom predmeta koji se u njemu uvaju (pretpostavlja se da jedan sanduk
uva samo istovrsne predmete), brojem predmeta koji se u njemu uvaju i teinom predmeta koji se u
njemu uvaju (svi su iste teine). Bure je opisano svojom teinom, nazivom tenosti koja se u njemu
uva, te teinom tenosti koja se u njemu uva. Informacijama o robi pohranjenoj u skladitu pristupa
se
pomou dinamiki alociranog niza pokazivaa koji pokazuju na objekte tipa Sanduk ili tipa Bure
(za tu svrhu, obje klase Sanduk i Bure e morati biti naslijeene iz neke zajednike apstraktne
bazne klase). Tom nizu pokazivaa se pristupa preko nekog od atributa pohranjenog unutar klase
Skladiste. Interfejs klasa Sanduk i Bure omoguava da se saznaju teine sanduka odnosno
bureta, sa i bez onoga to je u njima, kao i da se ispiu podaci o sanduku odnosno buretu i onome to
je u
njima (format ispisa odaberite po volji). Interfejs klase Skladiste treba sadravati sljedee
elemente:
Konstruktor sa jednim parametrom koji predstavlja maksimalnu koliinu objekata (sanduka odnosno
buradi) koji se mogu pohraniti u skladitu. Ovaj konstruktor se ne smije koristiti za automatsku
pretvorbu cijelih brojeva u objekte tipa Skladiste.
Destruktor, koji oslobaa svu memoriju koji su objekti tipa Skladiste zauzeli tokom svog
ivota.
Konstruktor kopije i preklopljeni operator dodjele koji omoguavaju bezbjedno kopiranje i
meusobno 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 skladite.
Parametri ovih metoda trebaju biti u skladu sa informacijama koje su potrebne da se opie sanduk
odnosno bure. Ukoliko je skladite ve popunjeno, treba baciti izuzetak.
Metode koje vraaju reference na najlaki odnosno najtei objekat (bure ili sanduk) u skladitu, ne
raunajui ono to je pohranjeno u tom objektu.
Metodu koja vraa broj objekata u skladitu ija je ukupna teina (tj. vlastita teina zajedno sa
teinom onoga to se u njima nalazi) vea od iznosa koji se zadaje kao parametar.
Metode koje ispisuju spisak svega to se nalazi u skladitu, sortiran u opadajui poredak po
ukupnoj teini.
Napisane klase demonstrirajte u testnom programu koji ita podatke o robi iz tekstualne datoteke,
smjeta robu u skladite i na kraju ispisuje sortirani spisak svega to se nalazi u skladitu. Svaki
objekat opisan je sa dva reda u datoteci. U prvom redu se nalazi poetno slovo S ili B (za sanduk
odnosno za bure) iza kojeg nakon jednog razmaka slijedi naziv predmeta ili tenosti koje su
pohranjene u sanduku odnosno buretu (npr. S Tepsije ili B Suncokretovo ulje). U drugom
redu se za sluaj sanduka nalazi teina sanduka, broj predmeta i teina svakog od njih, razdvojeno po
jednim razmakom (npr. 1.2 50 0.35) dok se za sluaj bureta nalazi teina bureta i teina tenosti
(npr. 0.8 16.5). Radi jednostavnosti, pretpostavite da datoteka sadri iskljuivo ispravne podatke.
NAPOMENA: U privatne dijelove klasa imate pravo stavljati ta god Vam treba da bi traene klase
funkcionirale u skladu sa postavkom zadatka.
Zadatak 2b (1,5 poen):
Opiite ta bi se tano izmijenilo u realizaciji prethodnog zadatka ukoliko bi se za pristup
informacijama

o robi pohranjenoj u skladitu umjesto dinamiki alociranog niza pokazivaa koji pokazuju na objekte
tipa Sanduk ili tipa Bure koristio vektor pokazivaa 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)

//
//
}

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;
}

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);

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>

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)

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];

}
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;
}

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;

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;
}

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);
}

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");

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;
}

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;

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)
{

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())

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);

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

ZADAE
Zadaa 1.
Ova zadaa nosi ukupno 4 poena (od 20 poena, koliko e ukupno nositi sve zadae 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 raunarstva. Rok za predaju ove
zadae je utorak, 27. III 2012. (do kraja dana) i ne moe se produiti. Zadae se predaju putem
Zamgera.
1. U nekom deseterospratnom skladitu nalazi se lift za prevoz tereta koji se upravlja uz pomo
raunarskog 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 sljedee komande za upravljanje liftom:
I Idi; P Promijeni smjer; K Kraj. Komanda I obavezno je praena jednim nenegativnim
cijelim brojem (npr. I 5) i ona pomjera lift za navedeni broj spratova u smjeru u kojem je lift
trenutno usmjeren. U sluaju da je nemogue pomjeranje za zadani broj spratova, treba prijaviti
poruku o greki. Komanda P mijenja smjer kretanja lifta, odnosno ukoliko se lift trenutno kree
nagore, nakon ove komande kretae se nadolje, i obrnuto. Komanda K zavrava program. Sve
druge komande su ilegalne, i trebaju dovesti do prijave greke i ponovnog izbora komande. Na
poetku rada, lift se nalazi u prizemlju i kree se nagore. Dijalog izmeu programa i korisnika
mogao bi izgledati poput sljedeeg:
Lift se nalazi u prizemlju i kree se nagore.
Unesi komandu (I Idi, P Promijeni smjer, K Kraj):
Pogrena komanda (nedostaje parametar)!
Unesi komandu (I Idi, P Promijeni smjer, K Kraj):
Lift se nalazi na 5. spratu i kree se nagore.
Unesi komandu (I Idi, P Promijeni smjer, K Kraj):
Lift se nalazi na 6. spratu i kree se nagore.
Unesi komandu (I Idi, P Promijeni smjer, K Kraj):
Lift se nalazi na 6. spratu i kree se nadolje.
Unesi komandu (I Idi, P Promijeni smjer, K Kraj):
Pogrena komanda!
Unesi komandu (I Idi, P Promijeni smjer, K Kraj):
Pogrena komanda (neispravan parametar)!
Unesi komandu (I Idi, P Promijeni smjer, K Kraj):
Pogrena komanda (neispravan parametar)!
Unesi komandu (I Idi, P Promijeni smjer, K Kraj):
Lift se nalazi na 6. spratu i kree se nadolje.
Unesi komandu (I Idi, P Promijeni smjer, K Kraj):
Pogrena komanda (neispravan parametar)!
Unesi komandu (I Idi, P Promijeni smjer, K Kraj):
Nije mogue pomjeranje za navedeni iznos spratova!
Unesi komandu (I Idi, P Promijeni smjer, K Kraj):
Lift se nalazi na 4. spratu i kree se nadolje.
Unesi komandu (I Idi, P Promijeni smjer, K Kraj):
Lift se nalazi u prizemlju i kree se nadolje.
Unesi komandu (I Idi, P Promijeni smjer, K Kraj):
Pogrena komanda (suvian parametar)!
Unesi komandu (I Idi, P Promijeni smjer, K Kraj):
Lift se nalazi na 4. spratu i kree se nagore.
Unesi komandu (I Idi, P Promijeni smjer, K Kraj):
Pogrena komanda (suvian parametar)!

I
I5
I1
P
S
IXY2
I2XY
I0
I-1
I8
I2
I4
P2
P
KK

Unesi komandu (I Idi, P Promijeni smjer, K Kraj): K


Dovidjenja!

Naravno, konkretan dijalog zavisi od toga ta je korisnik unio, ali poruke koje se ispisuju na
ekranu trebaju izgledati tano 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. Napiite funkciju SlikeUOgledalu koja kao parametar prima vektor cijelih brojeva a koja
kao rezultat vraa novi vektor koji sadri brojeve koji su slika u ogledalu odgovarajuih brojeva
iz prvog vektora, odnosno koji se od odgovarajuih 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 vraa kao rezultat treba redom da sadri
elemente 723, 24, 5, 72164, 913 i 78. Napisanu funkciju demonstrirajte u testnom programu
koji trai da se sa tastature unose brojevi koji se smjetaju u neki vektor sve dok se sa tastature ne
unese nula (koja se ne smjeta u vektor), a koji nakon toga poziva napisanu funkciju da odredi
slike u ogledalu unesenih brojeva i ispie ih na ekran u vidu reenica oblika Slika u ogledalu
broja x glasi y i tako redom za sve brojeve. U programu ne treba testirati ispravnost unesenih
podataka, tj. pretpostaviemo da e korisnik programa zaista unositi brojeve. Napomena: nikakav
ispis ne treba vriti unutar funkcije, nego samo u glavnom programu!
3. Napiite funkciju BrojRijeci koja kao parametar prima jedan string (tj. parametar tipa
string) koji predstavlja neku reenicu, a koja vraa kao rezultat broj rijei unutar te reenice.
Pri tome se pod pojmom rije podrazumijeva svaka skupina susjednih znakova meu kojima
nema razmaka, takva da se ispred prvog znaka nalazi razmak (osim ukoliko se prvi znak nalazi na
samom poetku 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 rijei, 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 prikae u obliku n = p q2 gdje
su p i q prirodni brojevi takvi da p ima sve proste faktore razliite (tj. u rastavi broja p na proste
faktore niti jedan prosti faktor ne javlja se vie puta, odnosno sa eksponentom veim od 1). Na
primjer, imamo 28586250 = 42 8252, pri emu 42 ima sve proste faktore razliite (zaista, imamo
42 = 2 3 7). Ovakav prikaz nije teko dobiti nakon to prethodno rastavimo broj n na proste
faktore. Na primjer, imamo ovakav raun:
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 naene
vrijednosti p i q smjeta respektivno u parametre p i q. Na primjer, ukoliko se kao prvi
parametar zada broj 28586250, u drugi i trei parametar treba da se smjeste respektivno brojevi
42 i 825. U sluaju 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 odgovarajue brojeve p i q. Program
treba da testira da li je korisnik zaista unio broj i da prijavi odgovarajuu poruku o greki ukoliko
to nije sluaj. Obavezno predvidite i hvatanje eventualno baenog 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 tano dva djelioca, jedinicu i samog sebe. Prosti faktori nekog
broja su oni njegovi faktori koji su prosti brojevi.
Napomena 2: Dozvoljeno je u nekim sluajevima da bude p = 1 (to e se desiti kad god je n
kvadrat nekog cijelog broja, npr. 15876 = 1 1262) mada, strogo reeno, broj 1 nema prostih
faktora pa je malo diskutabilno rei da su svi njegovi prosti faktori razliiti.

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. Moe se desiti da matrica uope nema lokalnih minimuma ili maksimuma, a
moe se desiti da ih ima vie od jednog. Na primjer, sljedea 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)):

Napiite funkciju EkstremiMatrice koja kao prvi parametar prima matricu realnih brojeva
organiziranu kao vektor vektr realnih brojeva, a koja u drugi i trei parametar smjeta
respektivno broj lokalnih minimuma i broj lokalnih maksimuma matrice. Ukoliko preneseni
parametar nema strukturu matrice (tj. ukoliko svi redovi proslijeenog vektora vektr 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 nee biti baen, s obzirom da e se
funkciji iz glavnog programa uvijek prenositi ispravni parametri (tj. parametri koji zaista imaju
strukturu matrice). Meutim, s obzirom da dobro napisana funkcija ne treba nita da zna o tome u
kakvom e okruenju biti koritena, funkcija mora da se zna odbraniti u sluaju da u nju ipak
uu 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

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');

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)

{
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--)
{

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 RIJEI
#include <iostream>
#include <string>

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

#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)
{

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;

}
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;

cout<<"Ova matrica ima "<<max<<" lokalnih maksimuma."<<endl;


}
catch (...)
{
cout<<"Vas proslijedjeni vector nije matrica!";
}

return 0;
}

Zadaa 2.
Ova zadaa 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 raunarstva. Rok za predaju ove zadae je petak 13. IV 2012. (do kraja dana) i ne moe
se produiti. Zadae se predaju putem Zamgera.
Pitanje: Da li je mogue produiti rok za predaju zadae do nedjelje, 15. IV 2012. s obzirom
da je ispit u ponedjeljak, 16. IV 2012?
Odgovor: Ne.
Pitanje: Zato?
Odgovor: Ba zato to je ispit u ponedjeljak, 16. IV 2012. Zadaa se ne radi dan pred ispit. A
ni dva dana pred ispit. Posljednja dva dana pred ispit trebaju se iskoristiti na bolji
nain nego izradom zadae.
Pitanje: A ne moete odgoditi ni zbog injenice da se petak 13. smatra baksuznim danom?
Odgovor: Ne moe... Niste valjda toliko sujevjerni!?
Pitanje: Da li je ovo konaan stav?
Odgovor: Da (evo i jednog afirmativnog odgovora).
VANA NAPOMENA: Postoji mogunost da e se neki zadaci testirati automatskim testnim
skriptama. Da bi takvo testiranje ispravno radilo, sve funkcije se MORAJU ZVATI TANO
ONAKO KAKO JE SPECIFICIRANO i moraju primati TANO ONAKVE PARAMETRE KAKO
JE SPECIFICIRANO. U suprotnom e testna skripta odbaciti zadatak kao neispravan!!!
1. Napiite generiku 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, zadravajui ostale elemente u istom poretku kakvi su
bili prije odstranjivanja. Funkcija ne vraa nikakvu vrijednost, ve samo utie na elemente
parametra v (koji pri tome, naravno, moe promijeniti svoju veliinu). Na primjer, ako prije
poziva funkcije vektor v sadri 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 sadri 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 pomone vektore). Takoer, nije dozvoljeno koristiti nikakve biblioteke 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 takoer unosi putem tastature i ispisati sve kompleksne brojeve iz prvog spiska nakon
obavljenog odstranjivanja.
2. Napiite program koji od korisnika trai 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

nakon toga treba da ispie produkt dvije unesene matrice. Program treba da bude zasnovan na
skupini napisanih funkcija za rad sa matricama, koje radi univerzalnosti treba izvesti kao
generike funkcije (bez obzira to e se u ovom programu raditi samo sa matricama iji su
elementi realni brojevi). U programu treba da se nalaze sljedee funkcije: KreirajMatricu,
UnesiMatricu, PomnoziMatrice, IspisiMatricu i UnistiMatricu. Funkcija
KreirajMatricu prima kao parametre dvojni pokaziva koji slui za pristup dinamiki
kreiranoj matrici (u nastavku emo ovaj pokaziva prosto zvati dinamika matrica), kao i
dimenzije matrice n i m. Funkcija treba da alocira prostor za matricu formata n m i dodijeli
adresu alociranog prostora pokazivau koji se koristi za pristup njenim elementima. Funkcija
UnesiMatricu popunjava matricu elementima unesenim sa tastature, a prima kao parametre
dinamiku matricu i dimenzije n i m. Funkcija PomnoziMatrice prima kao parametre dvije
dinamike matrice i njihove dimenzije n1 i m1, odnosni n2 i m2. Ova funkcija treba da kreira
novu dinamiku matricu (pozivom funkcije KreirajMatricu), da je popuni proizvodom dvije
dinamike matrice koje su joj proslijeene kao parametri, i da vrati kao rezultat dvojni pokaziva
koji slui za pristup elementima novokreirane matrice. U sluaju da matrice nisu saglasne za
mnoenje, funkcija treba da baci izuzetak. Funkcija IspisiMatricu kao parametre prima
dinamiku 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. Konano,
funkcija UnistiMatricu unistava dinamiki kreiranu matricu koja joj se prosljeuje kao
parametar (zajedno sa dimenzijama n i m). Funkcija KreirajMatricu treba da baci izuzetak u
sluaju da kreiranje ne uspije. Pri tome, ova funkcija mora da vodi rauna da u sluaju da doe do
bacanja izuzetka poisti iza sebe sve uspjele alokacije, tako da ne doe do curenja memorije.
Eventualno baene izuzetak treba hvatati u glavnom programu. Obavezno testirajte sluaj kada
alokacija ne uspijeva (unosom prevelikih brojeva n i/ili m).
3. Na predavanjima je obraeno nekoliko korisnih funkcija iz biblioteke algorithm. Meu njima
su i funkcije min element, reverse i find if i replace copy if. Napiite
vlastite verzije ovih funkcije nazvane Najmanji, Izvrni, NadjiUvjetno i
KopirajUzZamjenuUvjetno, koje rade potpuno istu stvar kao i odgovarajue biblioteke
funkcije. Funkcije treba realizirati iskljuivo koritenjem pokazivake aritmetike. Bitno je da sve
funkcije moraju biti zasnovane na potpunoj dedukciji tipova, tako da ispravno rade i sa
pokazivaima 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 takoer unosi sa
tastature;
Umanjiti najmanji broj u deku za 1 (ukoliko ima vie 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 odgovarajuu poruku koja govori o tome);
Izvrnuti sve elemente deka, tako da prvi element postane posljednji, itd.
Iskopirati sve elemente tako izvrnutog deka u dinamiki 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 dinamiki alocirani niz.
U glavnom programu nije dozvoljeno koristiti petlje (osim za unos i ispis elemenata niza), ve
sve manipulacije treba ostvariti iskljuivo 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 moe prilino usloniti
implementaciju nekih od traenih funkcija. Jednu od njih ak neete moi implementirati bez da
napiete jednu pomonu funkciju (takoer generiku) koju ete pozivati iz nje (to naravno nije

zabranjeno). Sami ete uvidjeti zato.


Napomena 2: Pokazivaka aritmetika ne radi nuno 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 rauna o tome.
Napomena 3: Kao test da li Vam napisane funkcije rade ispravno, Va glavni program treba
identino raditi ukoliko pozive funkcija Najmanji, Izvrni, NadjiUvjetno i
KopirajUzZamjenuUvjetno zamijenite pozivima odgovarajuih bibliotekih funkcija.
4. Napravite funkciju SortirajRecenice koja kao parametar prima pokaziva koji pokazuje na
prvi element nekog dinamiki 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 due reenice nalaziti uvijek ispred kraih. U sluaju da dvije
reenice imaju istu duinu, tada reenica koja dolazi prije po abecednom poretku treba da doe
ispred reenice koja dolazi kasnije po abecednom poretku (pri tome ne treba praviti razliku
izmeu malih i velikih slova). Sortiranje treba obaviti uz pomo biblioteke funkcije sort (uz
definiranje odgovarajue funkcije kriterija). Napisanu funkciju treba demonstrirati u testnom
programu koji prvo trai da se sa tastature unese prirodan broj n, nakon ega dinamiki alocira niz
od n stringova i popunjava ih sa n reenica unesenih sa tastature. Program zatim sortira niz u
traeni 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
odgovarajueg komentara o tome) i da nakon toga obrie dinamiki alocirani niz. Binarnu
pretragu treba obaviti uz pomo odgovarajue biblioteke funkcije. Dobro obratite panju da niz
nije sortiran u uobiajenom poretku funkcija za obavljanje binarne pretrage to mora uzeti u
obzir!
5. Napiite program koji e Vas uvjeriti koliko je bolje koristiti biblioteku funkciju sort od
runog sortiranja. U programu ete prvo definirati dvije funkcije GenerirajNiz i
SortirajRucno. Funkcija GenerirajNiz treba da ima jedan cjelobrojni parametar n i
ona dinamiki alocira niz od n elemenata popunjen sluajnim realnim brojevima iz opsega od 0
do 1 i vraa kao rezultat pokaziva na prvi element tako kreiranog niza. Za generiranje sluajnih
brojeva koristite funkciju rand bez parametara iz biblioteke cstdlib koja kao rezultat vraa
sluajan 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 vrijednou 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 (identino kao
biblioteka funkcija sort). Ova funkcija vri sortiranje bloka u opadajui poredak koristei
neki od jednostavnih postupaka za sortiranje koji su Vam poznati (npr. BubbleSort, SelectionSort,
itd.). Funkcija bi trebala da bude generika, tako da moe sortirati u opadajui poredak niz
elemenata proizvoljnog tipa uz pretpostavku da se oni mogu meusobno 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
tane vrijednosti odrediti kasnije) a koji zatim dinamiki kreira dva niza sa respektivno n1 i
n2 elemenata. Nakon toga, prvi niz treba sortirati pozivom funkcije SortirajRucno, a
drugi pozivom biblioteke funkcije sort (uz odgovarajuu funkciju kriterija, s obzirom da se
trai sortiranje u opadajuem poretku). Testiranje zaponite od malih vrijednosti n1 i n2, a
zatim poveavajte ove vrijednosti sve dok trajanje svakog od sortiranja bude trajalo priblino 10
sekundi. Uporedite ove vrijednosti i sami izvucite zakljuak.
Napomena: Finalna verzija programa ne treba da trai nikakav unos podataka sa tastature
(konstante n1 i n2 trebaju da budu hard-kodirane, tj.fiksno upisane u program)!

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 smanjivi 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

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

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)


{

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;

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;

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>

#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;
};

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;

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;

//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();
}

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;

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;
}

Zadaa 3.

Ova zadaa nosi ukupno 4 poena, pri emu prvi zadatak nosi 0.7 poena, drugi 1 poen, trei 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 raunarstva. Rok za predaju ove zadae je
utorak,
8. V 2012. (do kraja dana) i ne moe se produiti. Zadae se predaju putem Zamgera.
1. Dopunite program matrica struct.cpp priloen uz Predavanje 7. sa dvije nove funkcije
ProduktMatrica i StepenMatrica. Funkcija ProduktMatrica prima dvije
matrice kao parametre (matrice su definirane kao odgovarajue strukture) i vraa njihov
produkt kao rezultat, odnosno baca izuzetak ukoliko matrice nisu saglasne za mnoenje.
Funkcija StepenMatrica prima matricu kao jedan parametar, kao drugi parametar prima
prirodan broj n, i kao rezultat vraa matricu dignutu na n-ti stepen (u matrinom smislu)
odnosno baca izuzetak ukoliko matrica nije kvadratna, s obzirom da je stepen matrice
definiran samo za kvadratne matrice (pri realizaciji ove funkcije moete koristiti ve napisanu
funkciju ProduktMatrica). Takoer, proirite funkciju IspisiMatricu dodatnim
parametrom treba_brisati tipa bool. Ukoliko ovaj parametar ima vrijednost true,
funkcija treba da oslobodi prostor zauzet matricom koja joj je proslijeena kao parametar, u
suprotnom ne treba da radi nita. Ovim se omoguava da moemo zadavati pozive poput
IspisiMatricu(ZbirMatrica(a, b), 7, true);

tako da se oslobaanje memorije koju je zauzela pomona matrica koja predstavlja zbir
matrica moe obaviti bez koritenja pomone 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. Takoer, dobro pazite da nigdje ne doe do
curenja memorije, ni pod kakvim okolnostima (u sutini, to je i osnovni cilj zadatka).
Napomena: Da, ovaj zadatak je ve bio za zadau u nekoliko prethodnih generacija. Naravno,
moete ga pooniti, ili Vam ga moe uraditi neko drugi. Ali da znate, to bi rekao
Balaevi, neko to od gore vidi sve, i prije ili kasnije to e Vam se od glavu razbiti. Izuzetno je
vano da barem ovaj zadatak zaista uradite sami (naravno, samostalno iste trebali uraditi i sve
ostale zadatke, ali je izuzetno vano da ba ovaj zadatak ne prepiete ni .po koju cijenu).
Ukoliko ne elite samostalno da uradite ovaj zadatak, radije ga nemojte ni predavati.
2. Zbog energetske krize, planiraju se restriktivna iskljuenja struje u pojedinim dijelovima
grada. Grad je podijeljen u blokove, numerirane redom od 1 do N. Plan je da svaki M-ti blok
poev od bloka 1 redom bude iskljuivan, nakon ega on ne dolazi u konkurenciju za ponovno
iskljuivanje sve dok svaki blok ne bude barem jednom iskljuen. Pri tome se podrazumijeva
da iza posljednjeg bloka ponovo dolazi blok sa rednim brojem 1, tako da se razbrajanje
obavlja ciklino. Nakon to svi blokovi dou na red, postupak se ponavlja ispoetka. Na
primjer, ukoliko u gradu ima 10 blokova (sa rednim brojevima 1 10) i ukoliko je M= 4,
redoslijed iskljuivanja je 1, 5, 9, 4, 10, 7, 6, 8, 3 i 2 (nacrtajte sliku), nakon ega ponovo
zapoinje isti ciklus iskljuenja.
Predloena strategija je oigledno pravina. Meutim, gospodin Hapo Kradibai, ugledni
predsjednik SPG-a (Stranke Pohlepnih Gulikoa), eli da kvart pod rednim brojem K u kojem
se nalazi sjedite njegove stranke bude posljednji iskljuen, da ne bi dolo do remeenja
priprema za predizbornu kampanju. Zbog toga on planira podmititi upravu Elektrodistribucije
da odabere takav broj M da kvart pod rednim brojem K bude posljednji iskljuen.
Va zadatak je da napravite program koji e gospodinu Kradibaiu pomoi 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 sadri redne blokove blokova koji se
iskljuuju poredane u redoslijedu iskljuivanja. Na primjer, ukoliko je N= 10 i M= 4, ova

funkcija vraa 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
rjeavanje problema srodnih opisanom problemu. Konkretno, prvo ete definirati vornu
strukturu Blok koja predstavlja jedan blok u gradu. Ona sadri polje redni broj tipa
int i polje sljedeci koje je po tipu pokaziva na strukturu tipa Blok. Polje
redni broj sadravae redni broj bloka, dok e polje sljedeci pokazivati na sljedei
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 krune ili cirkularne liste).
Nakon to je formirana traena lista, vri se kretanje kroz listu, polazei 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 smjeta 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 vie na blok na kojem se trenutno nalazimo nego na blok
koji slijedi iza njega (ime se blok efektivno odstranjuje iz razmatranja) i prelazimo na
sljedei blok. Tom prilikom, pomou operatora delete potrebno je izbrisati vor koji
odgovara odstranjenom bloku, da ne zauzima vie memoriju. Postupak se ponavlja dok se ne
eliminira svih N blokova, nakon ega vraamo vektor u kojem smo zapamtili redoslijed
odstranjivanja blokova.
Ve je reeno 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 iskljueni blok
bio upravo blok sa rednim brojem K. Ukoliko takvih koraka ima vie, funkcija vraa najmanji
mogui korak, a ukoliko sluajno takva vrijednost koraka ne postoji, funkcija kao rezultat
vraa 0 (postavljau zadatka nije poznato moe li se ovo ikada desiti, ali predvidimo i ovo za
svaki sluaj). Rad ove funkcije zasniva se na pozivanju funkcije Razbrajanje za razne
vrijednosti M sve dok se ne pronae potrebni korak. Napisane funkcije demonstrirajte u
testnom programu koji za zadane vrijednosti N i K ispisuje traeni korak razbrajanja koji
gospodin Hapo Kradibai treba saopiti Elektrodistribuciji da bi postigao eljeni cilj,
Napomena: Za izradu programa nije dozvoljeno koristiti koncepte koji nisu obraivani na
predavanjima niti na kursu OR (recimo, tipove list, set ili map, razne biblioteke
funkcije koje nisu obraivane, itd.).
3. Za potrebe neke aplikacije za dvodimenzionalnu kompjutersku grafiku, potrebno je razviti
klasu Tacka koja predstavlja taku u ravni, sa sljedeim 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 taku u koordinatnom poetku, dok konstruktor sa dva

parametra kreira taku na osnovu zadanih Dekartovih koordinata x i y. Istu stvar radi i metoda
Postavi (osim to omoguava naknadnu promjenu pozicije take. Metoda
PostaviPolarno radi slinu stvar samo na osnovu polarnih koordinata i (podsjetimo
se da je veza izmeu 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 podrana je u jezicima C/C++ ba pod tim imenom). Metode DajX, DajY, DajRo i
DajTheta vraaju kao rezultat odgovarajue Dekartove odnosno polarne koordinate take,
dok metode PostaviX i PostaviY omoguavaju promjenu x odnosno y koordinate take
(bez promjene preostale koordinate). Metoda DaLiJeKoordinatniPocetak vraa logiku
vrijednost tano ili netano u ovisnosti da li taka na koju je metoda primijenjena
predstavlja koordinatni poetak ili ne. Metoda Transliraj pomjera taku 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 taku za ugao koji se zadaje kao prvi parametar (u smjeru
suprotnom od kazaljke na satu) oko take koja se zadaje kao drugi parametar. Drugi parametar
kao podrazumijevanu vrijednost ima taku kreiranu u koordinatnom poetku, ime je
postignuto da se moe zadati samo jedan parametar (pri emu se tada rotacija vri oko
koordinatnog poetka). Za one koji nisu dovoljno upueni, recimo da se rotacijom take (x, y)
oko take (xc, yc) za ugao dobija taka (x, y) gdje je x = xc + (x xc) cos ( y yc) sin ,
y = yc + (x xc) sin+ (y yc) cos . Konano, klasa podrava i dvije prijateljske funkcije.
Funkcija DaLiSuIdenticne vraa logiku vrijednost tano ili netano u ovisnosti da li
su take koje su joj proslijeene kao parametri identine ili ne, dok funkcija Rastojanje
vraa kao rezultat rastojanje izmeu taaka koje su joj proslijeene kao parametri.
Implementirajte klasu sa navedenim osobinama, pri emu ete uzeti da su atributi klase
Dekartove koordinate take x i y. Napisanu klasu demonstrirajte u testnom programu koji trai
da se tastature unese prirodan broj n, koji zatim treba dinamiki alocirati niz od n taaka (tj.
objekata tipa Tacka) koje treba inicijalizirati na osnovu podataka koji se unose sa tastature
(podaci o svakoj taki se unose posebno). Nakon okonanja unosa, program treba prvo
translirati a zatim rotirati sve unesene take u skladu sa podacima koji se unose sa tastature, te
ispisati vrijednosti x, y, i za sve unesene take nakon obavljenih transformacija. Na kraju,
program treba ispitati da li meu unesenim takama ima jednakih taaka (rezultat ispitivanja
treba prikazati na ekranu), te pronai par taaka koje se nalaze na najmanjem meusobnom
rastojanju i ispisati koje su to take.
NAPOMENA: U testnom programu se oigledno ne testiraju sve metode klase. To ne znai da
one ostale metode koje nisu predviene u testnom programu ne moraju raditi ispravno.
4. Pri razvoju neke hipotetike aplikacije koja koristi klasu Tacka razvijenu u prethodnom
zadatku, uoeno je da e neki vitalni algoritmi u aplikaciji mnogo bre raditi ukoliko se
koordinate take 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 koristei ovako izmijenjen dizajn, ali tako da nova klasa zadri 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 rjeavanja Zadatka 3. pametno napiete pojedine metode
klase, neete ih uope morati mijenjati u novoj verziji klase (ideja je pisati metode tako da se
to vie oslanjaju na druge napisane metode). U suprotnom, moda ete morati iznova napisati
sve metode, to nije ba relaksirajue.
5. Definirajte i implementirajte klasu Trougao koja omoguava uvanje podataka koji opisuju
jedan trougao/trokut. Pri tome se trougao posmatra kao apstraktni geometrijski lik opisan
iskljuivo duinama svojih stranica, dok je njegov taan poloaj u ravni odnosno prostoru

posve nebitan. Klasa treba da ima sljedei 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 duine stranica odreene parametrima.
Konstruktor sa dva parametra kreira pravougli trougao pri emu parametri predstavljaju
duine kateta, dok konstruktor sa jednim parametrom kreira jednakostranini trougao pri emu
su duine svih stranica jednake vrijednosti parametra.. Metode Postavi (u tri varijante)
naelno obavljaju isti zadatak kao i odgovarajui konstruktori, a omoguavaju naknadnu
izmjenu podataka o trouglu. Svi konstruktori kao i metode Postavi trebaju baciti izuzetak
ukoliko nije mogue kreirati trougao sa zadanim parametrima. Degenerirani sluajevi u
kojima se trougao reducira na du (recimo trougao sa stranicama duine 1, 2 i 3, ili duine 2, 2
i 0) ili na taku (recimo, trougao sa duinama stranica 0, 0 i 0) takoer nisu dozvoljeni.
Statika metoda TestLegalnosti samo testira da li je mogue kreirati trougao sa
stranicama koje su zadane kao parametri (bez bacanja izuzetaka) i vraa kao rezultat logiku
vrijednost tano ili netano u zavisnosti da li je test uspio ili ne. Metoda
OcitajStranice smjeta vrijednosti stranica u promjenljive koje su proslijeene kao
parametri, dok funkcija OcitajUglove smjeta vrijednosti odgovarajuih uglova/kutova
izraene u radijanima u promjenljive koje su proslijeene kao parametri (pri tome je alfa ugao
naspram stranice a, itd.). Metode DajObim i DajPovrsinu respektivno daju kao rezultat
obim odnosno povrinu trougla. Metoda Ispisi ispisuje podatke o duinama stranica,
uglovima, obimu i povrini trougla (stil ispisa oblikujte po volji). Konano, prijateljske
funkcije DaLiSuPodudarni odnosno DaLiSuSlicni testiraju da li su dva trougla koja
im se prenose kao parametri podudarna odnosno slina i vraaju kao rezultat logiku
vrijednost tano ili netano ovisno od rezultata testiranja. Dva trougla su podudarna
ukoliko imaju identine 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 slina ukoliko su
im stranice proporcionalne (vrijedi ista primjedba).
Napisanu klasu demonstrirajte u testnom programu koji trai da se tastature unese prirodan
broj n, koji zatim treba kreirati vektor koji sadri n pokazivaa na trouglove (tj. objekte tipa
Trougao). Nakon toga, sa tastature treba unijeti podatke za n trouglova (podaci o svakom
trouglu se unose posebno), dinamiki kreirati odgovarajue trouglove (tj. objekte tipa
Trougao) inicijalizirane u skladu sa unijetim podacima i povezati ih sa odgovarajuim
pokazivaima unutar vektora. Ukoliko korisnik zada vrijednosti stranica od kojih se ne moe
formirati trougao, treba ispisati poruku upozorenja i zatraiti novi unos podataka za isti
trougao. Nakon okonanja unosa, program treba sortirati sve unesene trouglove u opadajui
poredak po povrini (tj. troguao sa veom povrinom dolazi prije trougla sa manjom
povrinom) i ispisati podatke o svim trouglovima nakon obavljenog sortiranja. Za sortiranje
obavezno koristiti biblioteku funkciju sort uz pogodno definiranu funkciju kriterija. Na
kraju, program treba pronai sve parove podudarnih i slinih trouglova i ispisati koji su to
trouglovi (ili obavijest da takvih parova nema).

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;
}
}

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)
{

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,mat
rica.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;

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;

}
2.HAPO KRADIBAI (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;//poveemo 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;

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)

{
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 previe vana 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;
}

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);

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->";

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);

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)

{
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;

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;

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->";

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;
}
}
}
}

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;

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);
}

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)

{
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[])
{

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;
}

Zadaa 4.
Ova zadaa nosi ukupno 3,6 poena, pri emu prvi i trei 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 raunarstva. Rok za predaju ove zadae je
etvrtak, 24. V 2012. (do kraja dana) i ne moe se produiti. Zadae se predaju putem Zamgera.
1. Implementirajte jednostavan program koji olakava voenje 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 sadri
privatne atribute koji uvaju informacije o evidencijskom (matinom) 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 sadri konstruktor sa 5 parametara koji
inicijalizira sve atribute na vrijednosti zadane parametrima, zatim trivijalne pristupne metode
DajEvidencijskiBroj, DajIme, DajPrezime, DajAdresu i DajTelefon
koje prosto vraaju vrijednosti odgovarajuih atributa, te metodu Ispisi koja ispisuje
podatke o lanu na ekran (format ispisa izaberite po elji). Klasa Knjiga sadri privatne
atribute koji uvaju informacije o evidencijskom broju knjige, naslovu, imenu pisca, anru i
godini izdavanja, kao i informaciju o eventualnom zaduenju knjige. Evidencijski broj i
godina izdavanja su cijeli brojevi, informacija o zaduenju uva se kao pokaziva na lana
koji je zaduio knjigu odnosno 0 ukoliko knjiga nije zaduena, dok su ostali atributi
stringovnog tipa. Interfejs klase sadri konstruktor sa 5 parametara koji inicijalizira sve
atribute klase na vrijednosti zadane parametrima, osim informacije o zaduenju koja se
postavlja tako da signalizira da knjiga nije zaduena. Pored konstruktora, interfejs klase sadri
trivijalne pristupne metode DajEvidencijskiBroj, DajNaslov, DajAutora,
DajZanr, DajGodinuIzdanja i DajKodKogaJe koje vraaju vrijednosti odgovarajuih
atributa, te metode ZaduziKnjigu, RazduziKnjigu, DaLiJeZaduzena i Ispisi.
Metoda ZaduziKnjigu vri zaduivanje knjige, a parametar joj je referenca na lana koji
zaduuje knjigu. Metoda RazduziKnjigu nema parametara, a vri razduivanje knjige.
Metoda DaLiJeZaduzena takoer nema parametara i prosto vraa logiku vrijednost
tano ili netano u ovisnosti da li je knjiga zaduena ili ne, dok metoda Ispisi vri
ispis podataka o knjizi na ekran (format ispisa izaberite po elji).
Podaci o svakom lanu odnosno svakoj knjizi uvaju se u dinamiki alociranim varijablama,
kojima se pristupa pomou dva vektora iji su elementi pokazivai na lanove (tj. na objekte
tipa Clan) odnosno pokazivai na knjige (tj. na objekte tipa Knjiga). Broj elemenata
ovih vektora nije unaprijed odreen, nego raste po potrebi sa dodavanjem novih lanova
odnosno knjiga u evidenciju. Program treba da korisniku ponudi izbor jedne od sljedeih
opcija, koje se izvravaju u petlji sve dok korisnik ne odlui da zavri rad:
a) Registriranje novog lana. Izborom ove opcije, program treba pitati korisnika o linim
podacima lana, nakon ega se kreira odgovarajui objekat tipa Clan i upisuje u
evidenciju. Program ne smije dozvoliti kreiranje lana iji se evidencijski broj poklapa sa
evidencijski brojem nekog od ve postojeih 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 ispie 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 odgovarajui objekat tipa Knjiga i
upisuje u evidenciju. Program ne smije dozvoliti kreiranje lana iji se evidencijski broj
poklapa sa evidencijski brojem nekog od ve postojeih lanova.
e) Zaduivnje knjige. Izborom ove opcije, program treba pitati korisnika o evidencijskom

broju knjige, kao i o evidencijskom broju lana koji zaduuje knjigu, nakon ega se
registrira da je knjiga zaduena kod navedenog lana. U sluaju da je neki od
evidencijskih brojeva neispravan, ili ukoliko je knjiga ve zaduena, treba prikazati
odgovarajuu poruku o greki.
f) Razduivanje knjige. Izborom ove opcije, program treba pitati korisnika o evidencijskom
broju knjige, nakon ega registrira da knjiga nije vie zaduena. U sluaju da je
evidencijski broj neispravan, ili ukoliko knjiga nije zaduena, treba prikazati odgovarajuu
poruku o greki.
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 zaduena, treba ispisati i osnovne
podatke o lanu kod koga se knjiga nalazi (evidencijski broj, ime i prezime). U suprotnom,
treba ispisati da knjiga nije zaduena.
h) Izlistavanje knjiga. Izborom ove opcije, program treba da ispie podatke o svim
registriranim lanovima, jedan za drugim.
i) Prikaz zaduenja. Izborom ove opcije, program treba pitati korisnika o evidencijskom
broju lana, nakon ega ispisuje podatke o svim knjigama koje je zaduio navedeni lan,
ili informaciju da taj lan nema zaduenja. U sluaju da je evidencijski broj neispravan,
treba prikazati odgovarajuu poruku o greki.
j) Kraj programa. Izborom ove opcije, program zavrava sa radom.
2. Izmijenite program ucenici_obp.cpp priloen uz Predavanje 10 u skladu sa sljedeim
zahtjevima:
a) Atributi ime i prezime u klasi Ucenik sada e biti tipa string umjesto niza
znakova. Kao posljedica toga, konstruktor klase Ucenik treba takoer da se promijeni,
tim prije to vie nije potrebno provjeravati da li je preena maksimalna dozvoljena duina
imena odnosno prezimena.
b) Ocjene se vie nee 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 dinamiki alociranih objekata tipa Ucenik umjesto
dinamiki alociranog niza pokazivaa treba koristiti vektor iji su elementi pokazivai na
objekte tipa Ucenik. Pri tome, atributi koji uvaju broj upisanih uenika i kapacitet
razreda vie nee biti potrebni. Zaista, broj upisanih uenika se moe saznati testiranjem
trenutne veliine vektora, dok kapacitet razreda vie nije potrebno zadavati, s obzirom da
vektor moe u toku rada po volji poveavati svoju veliinu. Samim tim, konstruktoru vie
nee biti potreban parametar (zahvaljujui fleksibilnosti vektora, moi e se upisati
onoliko uenika koliko elimo, bez potrebe da unaprijed specificiramo njihov maksimalan
broj). Isto tako, metoda za evidentiranje novog uenika vie ne treba provjeravati da li je
dostignut maksimalan broj studenata, s obzirom da ogranienje na maksimalan broj
uenika vie ne postoji. Destruktor e i dalje biti potreban (da oslobodi sve dinamiki
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 omogui bezbjedno kopiranje i meusobno dodjeljivanje objekata tipa
Razred, zasnovano na strategiji dubokog kopiranja. Naime, treba primijetiti da su
dinamiki alocirani objekti tipa Ucenik u vlasnitvu klase Razred, iako nisu njen
sastavni dio (razmislite dobro ta konstruktor kopije i preklopljeni operator dodjele tano
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 poneto dodati i u glavni program), i da nigdje ni pod kakvim okolnostima ne dolazi do
curenja memorije.

3. Za potrebe rekonstrukcija eljeznica Bosne i Hercegovine, potrebno je napraviti program koji


e vriti automatsku najavu polazaka preko ozvuenja na eljeznikoj stanici. Program treba
najavljivati sve vozove koji odlase sa stanice u toku dana, kao i eventualna kanjenja 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 sljedei 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 odredita, 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 vonje u minutama, kao i
informaciju o eventualnom kanjenju (takoer u minutama). Konstruktor inicijalizira objekat u
skladu sa vrijednostima zadanim parametrima konstruktora, osim informacije o eventualnom
kanjenju, 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 kanjenju na vrijednost zadanu parametrom, dok metoda
DaLiKasni omoguava da se sazna da li odgovarajua vonja kasni ili ne (metoda vraa
logiku vrijednost true u sluaju kanjenja, a logiku vrijednost false u suprotnom
sluaju). Metoda DajTrajanje daje kao rezultat trajanje vonje u minutama, dok metode
OcekivanoVrijemePolaska i OcekivanoVrijemeDolaska omoguavaju da se sazna
oekivano vrijeme polaska odnosno dolaska kada se urauna iznos kanjenja u odnosu na
predvieno vrijeme polaska/dolaska. Obje metode treba da smjeste sate i minute oekivanog
vremena polaska/dolaska u dva cjelobrojna parametra koji joj se prosljeuju. Konano, metoda
Ispisi treba da podri ispis objekata tipa Polazak na ekran. U sluaju da se radi o
polasku bez kanjenja, ispis bi trebao da izgleda poput sljedeeg:
Lokalni voz broj 3423, odredite Zenica, polazi sa perona 2 u 15:40, a na odredite stie 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 ozvuenja, ali za potrebe ovog zadatka zadovoljiemo se
prostim ispisom na ekran.
U sluaju da se radi o polasku koji kasni, ispis bi trebao da izgleda poput sljedeeg:
Brzi voz broj 358, odrediste Ploe, sa predvienim vremenom polaska u 6:40, kasni oko 35
minuta, te e poi oko 7.15. Oekuje se da voz stigne na odredite oko 10:30. Izvinjavamo se
putnicima zbog eventualnih neugodnosti.
Klasa RedVoznje ima sljedei 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;

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

Podaci o polascima se uvaju u dinamiki alociranim objektima tipa Polazak, kojima se


opet pristupa preko dinamiki alociranog niza pokazivaa na takve objekte. Alokacija tog niza
pokazivaa vri se iz konstruktora. Parametar konstruktora predstavlja maksimalan broj
polazaka koji se mogu registrirati. Destruktor oslobaa svu memoriju koja je zauzeta tokom
ivota objekta, dok konstruktor kopije i preklopljeni operator dodjele omoguavaju bezbjedno
kopiranje i meusobno dodjeljivanje objekata tipa RedVoznje koritenjem strategije
dubokog kopiranja. Metoda RegistrirajPolazak podrana je u dvije verzije. Prva
verzija kreira novi polazak u skladu sa parametrima (koji su identini 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 nain kreiran)
i registira ga u kolekciji. U oba sluaja, treba baciti izuzetak u sluaju 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 prosjeno trajanje svih
registriranih vonji u minutama. Metode DajPrviPolazak i DajPosljednjiPolazak
daju kao rezultat prvi i posljednji polazak (tj. odgovarajui objekat tipa Polazak) u toku
dana (ukljuujui i eventualna kanjenja). Obje metode vraaju kao rezultat referencu da se
izbjegne nepotrebno kopiranje objekata. Metoda IsprazniKolekciju uklanja sve
registrirane polaske, tako da je nakon poziva ove metode kolekcija u identinom stanju kakva
je bila neposredno nakon kreiranja. Konano, metoda Ispisi ispisuje informacije o svim
polascima, poev od zadanog vremena do kraja dana, sortiranu po oekivanim vremenima
polazaka (za sortiranje iskoristite funkciju sort, uz pogodno definiranu funkciju kriterija
koja treba biti privatna statika funkcija lanica klase). Ispis pojedinanih polazaka vri 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 napiite 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 sluaju 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

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_t
elefona(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

Knjiga(int Evidencijski_knjige, string Naslov, string ImePisca, string Zanr, int


GodinaIzdavanja):Evidencijski_knjige(Evidencijski_knjige),Naslov(Naslov),ImePisca(ImePis
ca),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()

{
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 2Pretraga 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;

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)

{
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++)

{
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;

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())
{

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

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;
}

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;
}

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()
{

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)

{
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;
}

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++)

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;
};

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_v
oznje)%60
<<". Putnicima i voznom osoblju zelimo ugodno putovanje."<<endl;

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_v
oznje)%60
<<". Putnicima i voznom osoblju zelimo ugodno putovanje."<<endl;
}
/*Brzi voz broj 358, odrediste Ploe, sa predvienim vremenom polaska u 6:40, kasni oko
35
minuta, te e poi oko 7.15. Oekuje se da voz stigne na odredite 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)%6
0<<".Ocekuje se da voz stigne na odrediste oko "<<
sat_polaska+((minute_polaska+trajanje_voznje+kasnjenje)/60)<<":"<<(minute_polaska+traja
nje_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)%6
0<<".Ocekuje se da voz stigne na odrediste oko "<<
sat_polaska+((minute_polaska+trajanje_voznje+kasnjenje)/60)<<":"<<(minute_polaska+traja
nje_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):

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;

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;
};

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;

}
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;

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++)
{

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;

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

Zadaa 5.
Ova zadaa nosi ukupno 3 poena, pri emu prvi zadatak nosi 1,3 poena, drugi zadatak nosi 0,7
poena, dok trei zadatak nosi 1 poen. Sva tri zadatka se mogu uraditi na osnovu gradiva sa prvih 11
predavanja i pretpostavljenog predznanja iz predmeta Osnove raunarstva. Rok za predaju ove
zadae je etvrtak, 7. VI 2012. (do kraja dana) i ne moe se produiti. Zadae se predaju putem
Zamgera.
1. Definirajte i implementirajte klasu Datum koja omoguava uvanje datumskih podataka.
Negdje u javnom dijelu klase (interfejsu) nalaze se sljedee deklaracije:
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);

Pored ovoga, interfejs klase treba da sadri sljedee elemente:


a) Dva konstruktora sa tri parametra koji inicijaliziraju datum u skladu sa vrijednostima za
dan, mjesec i godinu koji se zadaju putem parametara. Podrana su dva naina kako se
moe zadati mjesec: kao vrijednost tipa Mjeseci koji je lokalno definiran u interfejsu
klase, ili kao cijeli broj u opsegu od 112 (zbog toga su i potrebna dva konstruktora). U
sluaju da datum nije smislen, treba baciti izuzetak.
b) Dvije metode nazvane Postavi koje u naelu obavljaju isti zadatak kao i konstruktori,
ali olakavaju naknadnu promjenu pohranjenih informacija.
c) Metode DajDan, DajMjesec i DajGodinu koje slue za oitavanje 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 sluiti samo za potrebe ispisivanja, rezultat ne treba
biti tipa string, nego tipa pokazivaa na znakove (tako da se umjesto itavog imena
vraa se samo pokaziva na prvi znak imena).
e) Metodu DajBrojDanaUMjesecu koja vraa koliko ukupno dana ima onaj mjesec koji
je trenutnu pohranjen u datumu.
f) Metodu DaLiJePrestupna vraa informaciju o tome da li je godina koja se uva u
datumu prestupna ili ne.
g) Metode DajDanUGodini i DajSedmicu vraaju kao rezultat redni broj dana
odnosno sedmice koji odgovaraju posmatranom datumu unutar godine koja se uva u
datumu.
h) Metodu DanUSedmici koja vraa dan u sedmici koji odgovara podacima zapamenim

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 slian nain kao i metoda DajImeMjeseca.
i) Preklopljene operatore ++ i , koji pomjeraju datum za jedan dan unaprijed
odnosno unazad (potrebno je podrati 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
rauna da taj cijeli broj moe 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 omoguava oduzimanje dva primjera klase Datum, pri
emu se kao rezultat dobija broj dana izmeu dva datuma.
m) Preklopljene relacione operatore ==, !=,<,>,<= i >= koji daju rezultat
poreenja dva datuma (u hronolokom 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 taka, zatim puno ime mjeseca (rijeima) iza koje slijedi razmak, zatim redni
broj godine iza kojeg takoe slijedi taka i, konano, ime odgovarajueg dana u sedmici u
zagradama. Na primjer, ukoliko je u datumu zapamen 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
sluaju da unos nije ispravan (to ukljuuje ne samo besmislene datume nego i sluajeve
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 moe
stati u jedan red ekrana. Obavezno napiite i mali testni program u kojem e se testirati svi
zahtijevani elementi ove klase.
Uputa: to se tie raunanja dana u sedmici koji odgovara zadanom datumu, najbolje je da
prvo izraunate broj dana koji je protekao izmeu 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 nain, naroito zbog prestupnih godina), a zatim izraunate
ostatak dijeljenja tog broja dana sa 7. Na osnovu tog ostatka i poznate injenice na koji je dan
pao referentni datum, vrlo lako se zakljuuje na koji dan pada posmatrani datum.
2. Linearne funkcije jedne realne promjenljive predstavljaju vjerovatno najvie koritene funkcije
u svim oblastima nauke i tehnike. To su funkcije koje se mogu predstaviti analitikim 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 opu klasu (moemo je nazvati
recimo LinFun) pomou koje se mogu kreirati objekti koji se ponaaju 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 sljedeem 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, predvieno je da se sa objektima tipa LinFun mogu vriti i razliite manipulacije,
u skladu sa opisom koji slijedi. Klasa LinFun kao jedine svoje atribute sadri koeficijent

pravca i slobodni lan odgovarajue linearne funkcije. Definirajte i implementirajte klasu sa


navedenim osobinama, znajui da njen interfejs sadri sljedee elemente (sve metode koje su
inspektori trebaju obavezno biti oznaene kao takve):

a) Konstruktore, koji omoguavaju kreiranje objekata tipa LinFun. Predvieno je da se


objekti ovog tipa mogu kreirati na vie razliitih naina. Mogue je pri kreiranju zadati
dva parametra, koji redom predstavljaju koeficijent pravca i slobodni lan linearne
funkcije koja se kreira. Dalje, mogue je zadati samo jedan parametar, koji tada
predstavlja slobodni lan, dok se koeficijent pravca postavlja na nulu (time se faktiki
kreira konstantna linearna funkcija). Konano, objekte tipa LinFun mogue je kreirati i
bez zadavanja ikakvih parametara. U tom sluaju, i koeficijent pravca i slobodni lan se
postavljaju na nulu. Potrebno je podrati 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
razliita naina, to ne znai nuno da moraju postojati tri konstruktora ako moete proi
sa manje, tim bolje po Vas.
b) Metodu Postavi sa dva parametra koja omoguava naknadnu promjenu koeficijenta
pravca i slobodnog lana ve definirane linearne funkcije (tj. objekta tipa LinFun).
c) Pristupne metode DajKoeficijentPravca i DajSlobodniClan bez parametara
koje omoguavaju 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 omoguavaju 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 omoguiti i sabiranje odnosno
oduzimanje funkcije i broja, odnosno broja i funkcije.
f) Preklopljeni binarni operator * koji omoguava mnoenje linearne funkcije realnim
brojem, odnosno realnog broja linearnom funkcijom. Kao rezultat se dobija nova linearna
funkcija iji su koeficijent pravca i slobodni lan pomnoeni zadanim brojem. Mnoenje
dvije linearne funkcije ne treba podrati, jer rezultat takvog mnoenja nije linearna
funkcija.
g) Preklopljeni binarni operator / koji omoguava 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 podrati, jer rezultat takvog dijeljenja nije linearna
funkcija.
h) Preklopljene operatore +=, =, *= i /= koji omoguavaju da izrazi poput
X += Y, X = Y, X *= Y i X /= Y imaju isto znaenje 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 poveavaju odnosno smanjuju slobodni lan u
linearnoj funkciji na koju je primijenjen za jedinicu. Potrebno je podrati i prefiksne i
postfiksne verziju ovog operatora.
j) Preklopljeni operator () koji omoguava izraunavanje 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 sluaju dijeljenja nulom, treba baciti izuzetak.
Obavezno napiite i mali testni program u kojem ete testirati sve elemente napisane klase.
3. Za potrebe neke meteoroloke stanice neophodno je vrsiti estu registraciju koliine padavina.
Za tu svrhu meteoroloka stanica koristi raunarski program u kojem je definirana i
implementirana klasa nazvana Padavine. Ova klasa omoguava uvanje podataka o

koliini padavina za izvjesni vremenski period u dinamiki alociranom nizu cijelih brojeva,
kojem se pristupa preko odgovarajueg privatnog atributa (koliina padavina se zadaje u
centimetrima, zaokrueno na cijeli broj). Pored ovog atributa (i eventualno drugih privatnih
atributa neophodnih za normalno funkcioniranje klase), poznato je da klasa sadri sljedee
elemente:
a) Konstruktor sa dva parametra, koji redom predstavljaju maksimalan broj koliina
padavina koje se mogu registrirati, odnosno maksimalno dozvoljenu koliinu padavina.
Ovaj konstruktor je odgovoran za dinamiku 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 vraanje kao rezultata iz funkcije, kao i
preoklopljeni operator dodjele = koji obezbjeuje sigurnu dodjelu jednog objekta tipa
Padavine drugom.
d) Metodu koja vri registraciju nove koliine padavina, pri emu se koliina padavina koja
se registrira prenosi kao parametar metode. U sluaju da se dostigne maksimalan broj
koliina padavina koje se mogu registrirati, ili u sluaju da je koliina padavina manja od
nule ili vea od maksimalne dozvoljene koliine padavina, metoda treba da baci izuzetak.
e) Metodu koja daje broj registriranih koliina padavina.
f) Metodu koja brie sve unesene koliine padavina.
g) Metode koje vraaju kao rezultat minimalnu i maksimalnu koliinu padavina (u sluaju
da nema registriranih koliina padavina, obje metode treba da bace izuzetak). Za
realizaciju nije dozvoljeno koristiti petlje, nego odgovarajue funkcije i/ili funktore iz
biblioteka algorithm i functional.
h) Metode koje vraaju kao rezultat broj dana u kojima je koliina padavina bila vea
odnosno manja od od vrijednosti koja se zadaje kao parametar (u sluaju da nema
registriranih koliina padavina, metode treba da bace izuzetak). Za realizaciju nije
dozvoljeno koristiti petlje, nego odgovarajue funkcije i/ili funktore iz biblioteka
algorithm i functional.
i) Metodu koja ispisuje sve unesene (registrirane) koliine padavina sortirane u opadajuem
poretku (tj. najvea koliina padavina se ispisuje prva), pri emu se svaka koliina
padavina ispisuje u posebnom redu. Pri tome je neophodno koristiti funkcije i/ili funktore
iz biblioteka algorithm i functional.
j) Preklopljeni operator [] koji omoguava da se direktno pristupi i-toj registriranoj
koliini padavina (numeracija ide od jedinice). Ukoliko je indeks izvan dozvoljenog
opsega, treba baciti izuzetak.
k) Preklopljeni operator ++ koji poveava sve registrirane koliine padavina za jedinicu
(pri tome se za jedinicu poveava i informacija o maksimalno dozvoljenoj koliini
padavina). Potrebno je podrati kako prefiksnu, tako i postfiksnu verziju ovog operatora.
Za realizaciju nije dozvoljeno koristiti petlje, nego odgovarajue funkcije i/ili funktore iz
biblioteka algorithm i functional.
l) Preklopljene operatore + i - koji djeluju na sljedei nain: Ukoliko je X objekat
tipa Padavine, a Y cijeli broj, tada je X + Y novi objekat tipa Padavine u
kojem su sve registrirane koliine padavina poveane za iznos Y (u novodobijenom
objektu treba aurirati informaciju o maksimalno dozvoljenoj koliini padavina). Na
slian nain se interpretira i izraz X - Y u sluaju da je X objekat tipa Padavine, a
Y cijeli broj. Pri tome, ukoliko se kao rezultat sabiranja ili oduzimanja dobije da neka
od koliina padavina postane negativna, treba baciti izuzetak. U sluaju kada su i X i
Y objekti tipa Padavine, tada je izraz X - Y novi objekat tipa Padavine koji
sadri razlike odgovarajuih koliina padavina iz objekata X i Y. U ovom posljednjem
sluaju se podrazumijeva da X i Y sadre isti broj registriranih koliina padavina, kao

i da su registrirane padavine u objektu X vee ili jednake od odgovarajuih registriranih


padavina u objektu Y (u suprotnom, treba baciti izuzetak). U svim ostalim sluajevima,
znaenje izraza X + Y odnosno X - Y nije definirano. Za realizaciju ovih operatora
nije dozvoljeno koristiti petlje, nego odgovarajue funkcije i/ili funktore iz biblioteka
algorithm i functional.
m) Preklopljene operatore += i -= iji je cilj da znaenje izraza oblika X += Y
odnosno X = Y bude identino znaenju 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 koliine padavina oduzete od maksimalno dozvoljene koliine padavina. Za
realizaciju nije dozvoljeno koristiti petlje, nego odgovarajue 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 sadre
isti broj registriranih koliina padavina, i ukoliko su sve odgovarajue registrirane
koliine padavina oba objekta jednake. Za realizaciju ovih operatora nije dozvoljeno
koristiti petlje, nego odgovarajue 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 napiite 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,De
cembar};
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]++;

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);

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;

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;

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;

}
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)
{

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;

}
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;

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)

{
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));

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;

}
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);

cin>>znak;
if (znak!='/')cin.setstate(ios::failbit);
cin>>mjesecp;
if ( danp < 1 || mjesecp < 1 || mjesecp > 12 || danp > broj_dana[mjesecp1])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[mjesecp1])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);

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);

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;

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)
{

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)

{
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;
}

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_padav
ina),
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;

}
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;

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;
}

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;
}

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){

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;
}

Zadaa 6.
Ova zadaa nosi ukupno 3,4 poena, pri emu prvi zadatak nosi 1,1 poen, drugi zadatak nosi 1,5
poen, dok trei zadatak nosi 0,8 poena. Sva tri zadatka se mogu uraditi na osnovu gradiva sa prvih
13 predavanja i pretpostavljenog predznanja iz predmeta Osnove raunarstva. Rok za predaju
ove
zadae je etvrtak, 14. VI 2012. (do kraja dana) i ne moe se produiti (nemojte pitati moe li se
produiti do dana ispita ne moe). Zadae se predaju putem Zamgera.
Napomena: Nije greka injenica da sve zadae 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++
sadri standardnu biblioteku set i istoimeni tip podataka koja omoguava rad sa
skupovima. Zbog nedostatka prostora, ova biblioteka i ovaj tip podataka nisu razmatrani na
kursu Tehnika programiranja, meutim zainteresirani mogu lako pronai (recimo, na internetu)
informacije o tome kako se ovaj tip podataka moe koristiti. Meutim, ovdje je Va zadatak da
sami razvijete generiku klasu Skup sline funkcionalnosti (koja dodue nee ni izbliza biti
efikasna koliko je biblioteki tip podataka set, pogotovo kada je broj pohranjenih podataka
velik, ali za vjebu e lijepo posluiti). Generika klasa Skup e predstavljati skup iji
elementi mogu biti proizvoljnog, ali istog tipa. Drugim rijeima, svi elementi skupa moraju
biti istog tipa, tako da skupovi heterogenog sastava nee biti podrani. Pored toga, za elemente
skupa emo pretpostaviti da se mogu porediti pomou operatora < (nije na odmet znati da
biblioteki tip podataka set posjeduje ista ova ogranienja). Klasa treba da ima sljedee
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 podri pretvorbu podataka tipa
vector u odgovarajui tip Skup. S obzirom da prema matematskoj definiciji skupa
skupovi ne mogu sadravati jednake elemente, prilikom kreiranja skupa viestruko
ponavljanje elemenata u vektoru treba ignorirati. Na primjer, ukoliko je vektor sadravao
redom elemente 3, 5, 2, 8, 2, 5, 2 i 1, kreirani skup sadravae 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 moe saznati iz samog niza.
e) Metodu DodajElement sa jednim parametrom, koja dodaje u skup element predstavljen
parametrom. U sluaju da se takav element ve nalazi u skupu, unos elementa treba
ignorirati.
f) Metodu DajKardinalniBroj bez parametara, koja vraa kao rezultat broj elemenata
skupa.
g) Metodu DaLiSadrzi sa jednim parametrom, koja vraa 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 podri ispis skupova na ekran. Skupovi se
ispisuju kao slijed svojih elemenata unutar vitiastih zagrada, meusobno razdvojenih
zarezima. Pri ispisu, elementi treba da budu sortirani u rastui poredak (redoslijed
elemenata je kod skupova svakako nebitan). Za sortiranje moete koristiti funkiju sort

(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 skraene 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 razliiti,
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 nuno negacija jedan drugog). Dakle, sve
relacione operatore moete definirati polazei samo od operatora <=.
Primijetimo da destruktor, konstruktor kopije i preklopljeni operator dodjele nee 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 napiite i testni program u kojem
ete demonstrirati sve elemente napisane generike klase uzimajui stringove (tj. objekte tipa
string) za elemente skupova.
2. Uprava ETF-a odluila je da uvede automatizirani fast-food restoran. Za potrebe automatske
obrade narudbi, potrebno je razviti program zasnovan na skupini klasa, prema opisu koji slijedi.
Klasa Obrok opisuje najjednostavniju narudbu, koja predstavlja neki obrok. Ova klasa od
atributa sadri naziv obroka (recimo Burek), cijenu obroka (realan broj) i puno ime (sa
prezimenom) studenta koji je naruio obrok. Pored ovih atributa, klasa sadri konstruktor koji
inicijalizira atribute na vrijednosti zadane parametrima, trivijalne pristupne metode
DajNazivObroka, DajCijenuObroka i DajNarucioca koje vraaju vrijednost svih
atributa, metodu Ispisi koja ispisuje podatke o izvrenoj narudbi (ispis formatirajte
prema vlastitoj elji) kao i metodu DajUkupnuCijenu koja vraa ukupnu cijenu narudbe.
U sluaju klase Obrok, ova metoda e samo vratiti cijenu obroka pohranjenu u atributu, ali
treba predvidjeti da e ova metoda biti eventualno izmijenjena u sloenijim klasama
naslijeenim iz klase Obrok kod kojih se ukupna cijena obroka formira na sloeniji nain.
Konano, klasa sadri i metodu DajKopiju koja kreira dinamiki alociranu kopiju objekta
nad kojim je pozvana (ova metoda e se koristiti za polimorfno kopiranje). Bitno je da treba
biti omogueno da se preko pokazivaa na klasu Obrok uvijek pozivaju ispravne verzije
svih metoda koje eventualno mogu biti promijenjene u naslijeenim klasama, bez obzira na tip
objekta na koji taj pokaziva pokazuje u trenutku poziva.
Klasa ObrokSaPicem opisuje narudbu koja uz obrok ukljuuje i pie. Ova klasa
naslijeena je iz klase Obrok, a od dodatnih atributa sadri i naziv pia (recimo Fanta)
kao i cijenu pia. U skladu s tim, klasa ima i dvije nove trivijalne pristupne metode
DajNazivPica i DajCijenuPica koje vraaju vrijednosti novouvedenih atributa
Konstruktor ove klase je izmijenjen u odnosu na konstruktor klase Obrok da omogui i
inicijalizaciju dopunskih atributa. Metoda koja vraa ukupnu cijenu narudbe modificirana je
tako da vrati ukupnu cijenu koja ukljuuje kako cijenu obroka, tako i cijenu pia. Isto tako,
modificirane su i metoda za ispis podataka o narudbi, koja sada treba ukljuiti i dopunske
informacije koje nisu postojale u klasi Obrok, ukljuujui i informacije o ukupnoj cijeni, te
metoda koja stvara dinamiki kreiranu kopiju objekta.

Klasa Narudzbe predstavlja kolekciju narudbi, izvedenu kao dinamiki niz pokazivaa na
objekte tipa Obrok ili ObrokSaPicem. Ova klasa sadri konstruktor sa jednim
parametrom, koji vri odgovarajuu dinamiku alokaciju memorije, pri emu parametar
predstavlja maksimalan broj zahtjeva koji se mogu pohraniti. Klasa sadri i odgovarajui
destruktor, koji oslobaa memoriju koju je objekat tipa Narudzbe zauzeo tokom svog
ivota, te konstruktor kopije i preklopljeni operator dodjele koji omoguavaju bezbjedno
kopiranje i meusobno dodjeljivanje objekata tipa Narudzbe zasnovano na strategiji
dubokog kopiranja. Od metoda, klasa Narudzbe posjeduje etiri metode. Prve dvije metode
NaruciObrok i NaruciObrokSaPicem vre kreiranje i dodavanje nove narudbe, pri
emu se prva metoda odnosi na prostu narudbu (obrok bez pia), dok se druga metoda odnosi
na narudbu obroka sa piem. Parametri ovih metoda su isti kao i konstruktori klasa Obrok
odnosno ObrokSaPicem. One kreiraju novu narudbu (u skladu sa navedenim parametrima)
i smjetaju ga u kolekciju. Trea metoda ObradiNaruzdbu nema parametara. Ona vri
ispis podataka o prvoj primljenoj narudbi na ekran (tj. narudbi koja najdue eka na
isporuku). Pored toga, ova metoda vri brisanje obraene narudbe iz kolekcije, tako da e
sljedei poziv ove metode ispisati sljedeu naredbu po redu, i tako dalje, sve dok se ne obrade
sve narudbe. U sluaju 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 logiku 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 logiku vrijednost false. Konano, klasa Narudzbe posjeduje i
preklopljeni operator [] koji kao rezultat daje ukupnu cijenu narudbi koje je naruio
student ije se ime navodi unutar uglastih zagrada (tj. zbir cijena svih narudbi tog studenta).
Ukoliko student sa navedenim imenom nije nita naruio, ovaj operator kao rezultat daje nulu.
Definirane klase treba demonstrirati u testnom programu koji obrauje narudbe 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
narudbama. Ova datoteka organizirana je tako da se za svaku narudbu u prvom redu nalazi
ime naruioca, u drugom redu naziv obroka, a u treem redu naziv pia (trei red se ostavlja
prazan ukoliko naruioc nije naruio pie). Narudbe su u datoteci pohranjene u redoslijedu
pristizanja. Na primjer, datoteka narudbi bi mogla izgledati recimo ovako:
aban auli
evapi u kajmaku
Jogurt
Zdravko oli
Krompirua
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 pie u prvom redu nalazi naziv obroka ili pia,
dok se u drugom redu nalazi cijena za navedeni obrok ili pie (u KM). Recimo, ova datoteka
moe izgledati recimo ovako:
Burek
3
Sirnica
2.5
Zeljanica
2.5
Krompirua

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 narubama iz tekstualne datoteke NARUDZBE.TXT


uz konsultacije cjenovnika iz datoteke CIJENE.TXT i smjetati ih u kolekciju. Nakon to se
proitaju podatke o svim narudbama, testni program treba da ispie sve unesene narudbe u
redoslijedu pristizanja.
Program bi trebao da presree sve probleme koji bi se eventualno mogli pojaviti i da ispisuje
odgovarajue poruke upozorenja korisniku. Ovo ukljuuje recimo sluajeve kada ulazne
datoteke sadre podatke koji nisu u skladu sa oekivanjima, zatim sluajeve kada cjenovnik ne
sadri cijenu za neki narueni obrok ili pie, itd.
3. Na Predavanju 13. razmotrena su dva primjera programa od kojih prvi kreira binarnu datoteku
koja sadri podatke o studentima nazvanu STUDENTI.DAT, dok drugi program iitava
sadraj kreirane datoteke i obraunava prosjek studenata na osnovu podataka u datoteci.
Dopunite ovu kolekciju programa treim programom koji sortira sadraj datoteke
STUDENTI.DAT u opadajui poredak prema prosjenoj ocjeni, bez prethodnog uitavanja
datoteke u niz (dakle, sve manipulacije treba raditi direktno nad datotekom). Za sortiranje
koristite neki od naivnih algoritama sortiranja (npr. BubbleSort). U sluaju da dva studenta
imaju isti prosjek, prije treba doi 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 vie
puta unititi sadraj datoteke. Stoga, ukoliko ste napravili rezervnu kopiju, neete morati svaki
put kada unitite sadraj datoteke pokretati ponovo program za kreiranje datoteke i unositi
iznova podatke (to moe biti veoma muno). 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;

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]){}

//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;

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;
}}}