You are on page 1of 36

Laslo Kraus

REENI ZADACI
IZ

PROGRAMSKOG JEZIKA

C++

AKADEMSKA MISAO
Beograd, 2014

Laslo Kraus
REENI ZADACI IZ PROGRAMSKOG JEZIKA C++
etvrto, preraeno izdanje

Predgovor
Recenzenti
Dr Igor Tartalja
Dr ore urevi

Izdava
AKADEMSKA MISAO
Bulevar kralja Aleksandra 73, Beograd

Lektor
Anelka Kovaevi

Dizajn naslovne strane


Zorica Markovi, akademski slikar

Ova zbirka zadataka je pomoni udbenik za uenje programiranja na jeziku C++. Zadaci prate gradivo
autorove knjige Programski jezik C++ sa reenim zadacima. Podrazumeva se, kao i u toj knjizi, da je
italac savladao programiranje na jeziku C. Zbirka je namenjena za upotrebu u fakultetskoj nastavi, ali
moe da se koristi i za samostalno produbljivanje znanja iz programiranja.
Reenja svih zadataka su potpuna u smislu da priloeni programi mogu da se izvravaju na raunaru.
Pored samih tekstova programa priloeno je samo malo objanjenja, prvenstveno u obliku slika i formula.
Oekuje se da e izvoa nastave dati dodatna usmena objanjenja sluaocima. Uz malo vie napora
zadaci mogu da se shvate i samostalno. Uz svaki program dat je i primer izvravanja da bi se olakalo razumevanje rada programa.
Kroz zadatke, pored elemenata samog jezika, prikazani su osnovni principi objektno orijentisanog programiranja: sakrivanje podataka, ponovno korienje koda, nasleivanje i polimorfizam. Prikazani su i najee korieni postupci u programiranju: pretraivanje i ureivanje nizova, obrada znakovnih podataka,
rad s bitovima, rad s dinamikim strukturama podataka (kao to su liste i stabla) i rad s datotekama.
Posebna panja posveena je i inenjerskim aspektima programiranja: preglednosti, razumljivosti i efikasnosti.
Izvorni tekstovi svih programa iz ove zbirke mogu da se preuzmu preko Interneta sa adrese
home.etf.rs/~kraus/knjige/. Svoja zapaanja itaoci mogu da upute elektronskom potom na
adresu kraus@etf.rs.

tampa
Planeta print, Beograd

Beograd, oktobar 2014.


Laslo Kraus

Tira
300 primeraka

ISBN 978-86-7466-???-?

NAPOMENA: Fotokopiranje ili umnoavanje na bilo koji nain ili ponovno objavljivanje ove knjige - u
celini ili u delovima - nije dozvoljeno bez prethodne izriite saglasnosti i pismenog odobrenja izdavaa.

3 Operatorske funkcije ............................................................................................................................73

Sadraj

Predgovor .....................................................................................................................................................4
Sadraj ..........................................................................................................................................................4
Preporuena literatura ................................................................................................................................6
0 Pripremni zadaci .....................................................................................................................................7
Zadatak 0.1
Zadatak 0.2
Zadatak 0.3
Zadatak 0.4

Izostavljanje elemenata niza na osnovu binarne maske ....................................................8


Rekurzivno izraunavanje skalarnog proizvoda dva vektora............................................9
Presek dva skupa u dinamikoj zoni memorije ...............................................................10
Obrtanje redosleda elemenata jednostruko spregnute liste .............................................11

1 Proirenja jezika C................................................................................................................................13


Zadatak 1.1
Zadatak 1.2
Zadatak 1.3
Zadatak 1.4
Zadatak 1.5
Zadatak 1.6
Zadatak 1.7
Zadatak 1.8
Zadatak 1.9
Zadatak 1.10
Zadatak 1.11

Ispisivanje pozdrava ........................................................................................................14


Izraunavanje zbira niza brojeva.....................................................................................15
Ureivanje dinamikog niza brojeva...............................................................................16
Obrada jednostruko spregnute liste brojeva ....................................................................17
Ureivanje niza brojeva metodom podele.......................................................................18
Izostavljanje suvinih razmaka meu reima..................................................................20
Ureivanje imena gradova u dinamikoj matrici ............................................................21
Odreivanje polarnih koordinata take ...........................................................................23
Izraunavanje povrine trougla .......................................................................................24
Paket funkcija za obradu redova brojeva neogranienog kapaciteta...............................25
Paketi funkcija za obradu taaka, pravougaonika i nizova pravougaonika u ravni ........27

2 Klase .......................................................................................................................................................31
Zadatak 2.1
Zadatak 2.2
Zadatak 2.3
Zadatak 2.4
Zadatak 2.5
Zadatak 2.6
Zadatak 2.7
Zadatak 2.8
Zadatak 2.9
Zadatak 2.10
Zadatak 2.11
Zadatak 2.12
Zadatak 2.13

Take u ravni ...................................................................................................................32


Uglovi..............................................................................................................................33
Redovi brojeva ogranienih kapaciteta ...........................................................................35
Ureeni skupovi brojeva .................................................................................................38
Trouglovi u ravni.............................................................................................................41
Kvadri u dinamikoj zoni memorije................................................................................43
Krugovi u ravni koji ne smeju da se preklapaju..............................................................45
Kalendarski datumi..........................................................................................................48
Liste brojeva ....................................................................................................................51
Ureena stabla brojeva ....................................................................................................57
Nizovi materijalnih taaka...............................................................................................63
Liste datuma ....................................................................................................................66
JMBG, osobe i imenici....................................................................................................69

Zadatak 3.1
Zadatak 3.2
Zadatak 3.3
Zadatak 3.4
Zadatak 3.5
Zadatak 3.6
Zadatak 3.7
Zadatak 3.8
Zadatak 3.9
Zadatak 3.10
Zadatak 3.11
Zadatak 3.12
Zadatak 3.13
Zadatak 3.14

Kompleksni brojevi .........................................................................................................74


Vremenski intervali .........................................................................................................76
Nizovi kompleksnih brojeva ...........................................................................................78
Kvadri s automatski generisanim identifikacionim brojevima........................................80
Polinomi s realnim koeficijentima ..................................................................................82
Studenti koji ne smeju da se kopiraju..............................................................................86
Redovi brojeva neogranienih kapaciteta .......................................................................89
Tekstovi ...........................................................................................................................92
Tekstovi s utedom memorije..........................................................................................95
Karte i predstave..............................................................................................................99
Otpornici i redne veze otpornika ...................................................................................102
Zapisi artikala i inventari...............................................................................................105
Take, trouglovi, skupovi trouglova u ravni .................................................................109
Nalaenje minimuma funkcije.......................................................................................113

4 Izvedene klase ......................................................................................................................................115


Zadatak 4.1
Zadatak 4.2
Zadatak 4.3
Zadatak 4.4
Zadatak 4.5
Zadatak 4.6
Zadatak 4.7
Zadatak 4.8
Zadatak 4.9
Zadatak 4.10
Zadatak 4.11
Zadatak 4.12
Zadatak 4.13

Valjci i kante .................................................................................................................116


Osobe, aci i zaposleni..................................................................................................118
Neureene i ureene liste celih brojeva ........................................................................121
Predmeti, sfere i kvadri .................................................................................................124
Geometrijske figure, krugovi, kvadrati i trouglovi u ravni ...........................................127
Vektori, brzine i pokretni objekti i take u prostoru .....................................................132
Take, linije, dui, izlomljene linije i poligoni u ravni .................................................135
Objekti, skupovi objekata, kompleksni brojevi i tekstovi.............................................141
Geometrijska tela, sfere, valjci i redovi tela..................................................................147
Osobe, studenti i imenici ...............................................................................................151
Osobe, vozila, teretna vozila i putnika vozila..............................................................155
Izrazi, konstante, promenljive, dodele vrednosti i aritmetike operacije......................160
Naredbe, proste naredbe, sekvence, selekcije i ciklusi .................................................167

5 Izuzeci...................................................................................................................................................175
Zadatak 5.1
Zadatak 5.2
Zadatak 5.3
Zadatak 5.4
Zadatak 5.5
Zadatak 5.6
Zadatak 5.7
Zadatak 5.8
Zadatak 5.9
Zadatak 5.10
Zadatak 5.11
Zadatak 5.12
Zadatak 5.13

Vektori realnih brojeva sa zadatim opsezima indeksa ..................................................176


Racionalni brojevi .........................................................................................................179
Matrice racionalnih brojeva ..........................................................................................182
Nizovi, funkcije i verini razlomci................................................................................188
Podaci, skalarni podaci i nizovi.....................................................................................192
Funkcije i greke; izraunavanje odreenog integrala ..................................................197
Predmeti, celi brojevi, zbirke i nizovi predmeta ...........................................................203
Vektori, figure, take i mnogouglovi u prostoru ...........................................................208
Proizvodi, sfere, kvadri, maine i radnici......................................................................213
Radnici, prodavci, efovi i firme ...................................................................................219
Vozila, lokomotive, putniki vagoni i vozovi ...............................................................224
Elektrini potroai, ureaji, grupe ureaja i izvori ......................................................230
Funkcije za koje mogu da se stvaraju izvodi, delegati, monomi, eksponencijalne
funkcije i zbirovi funkcija .............................................................................................235

6 Generike funkcije i klase...................................................................................................................241


Zadatak 6.1 Generika funkcija za fuziju ureenih nizova...............................................................242
Zadatak 6.2 Generiki stekovi zadatih kapaciteta.............................................................................245
Zadatak 6.3 Generike klase za uporeivanje podataka i ureivanje nizova podataka ....................247
5

Zadatak 6.4 Generiki nizovi, boje, take, obojene figure, krugovi, pravougaonici, trouglovi,
mnogouglovi i crtei u ravni .........................................................................................249
Zadatak 6.5 Generike liste; datumi, osobe, ispiti, aci i kole ........................................................257
Zadatak 6.6 Vozila, bicikli, kamioni, generiki nizovi, etape, vonje i trkaki automobili .............263
Zadatak 6.7 Tereti, sanduci, burad, generiki nizovi, vozila, lokomotive, vagoni i vozovi .............269
Zadatak 6.8 Simboli, fontovi, vektori, dui, tekstovi, generiki nizovi i crtei................................276
Zadatak 6.9 Akteri, asovnici, proizvodi i generika skladita, proizvoai i potroai..................283
7 Standardna biblioteka.........................................................................................................................289
Zadatak 7.1
Zadatak 7.2
Zadatak 7.3
Zadatak 7.4
Zadatak 7.5
Zadatak 7.6
Zadatak 7.7
Zadatak 7.8

Stekovi i redovi taaka neogranienih kapaciteta .........................................................290


Predmeti, tela, sfere, kvadri i sklopovi..........................................................................294
Obrada sekvencijalne tekstualne datoteke.....................................................................299
Obrada reenica u tekstualnoj sekvencijalnoj datoteci .................................................300
Obrada sekvencijalne binarne datoteke.........................................................................301
Obrada relativne binarne datoteke.................................................................................303
Klasa renika .................................................................................................................305
Klasa relativnih binarnih datoteka i obrada liste u relativnoj binarnoj datoteci ...........309

0 Pripremni zadaci

Preporuena literatura

[1] Laslo Kraus: Programski jezik C++ sa reenim zadacima, deveto, znatno preraeno izdanje, Akademska misao, Beograd, 2014.
[2] Working Draft, Standard for Programming Language C++, American National Standards Institute,
2012.
[3] C++ Reference, http://en.cppreference.com/w, 2014.
[4] Bjarne Stroustrup: The C++ Programming Language, Third Edition, Addison-Wesley Publishing
Company, Reading, Massachusetts, 1997.
[5] Laslo Kraus: Programski jezik C sa reenim zadacima, deveto, preraeno izdanje, Akademska misao, Beograd, 2014.
[6] Laslo Kraus: Reeni zadaci iz programskog jezika C, etvrto, preraeno izdanje, Akademska misao, Beograd, 2014.

Zadatak 0.1

Izostavljanje elemenata niza na osnovu binarne maske

Zadatak 0.2

Napisati na jeziku C funkciju za izostavljanje svih elemenata numerikog niza niz duine n elemenata
za koje na odgovarajuim mestima niza bitova maska stoji 0. Niz bitova se smeta u potreban broj
bajtova od kojih svaki (sem moda poslednjeg) sadri po 8 bitova.
Napisati na jeziku C program za ispitivanje prethodne funkcije.
Reenje:
j:

Napisati na jeziku C program koji proita dva vektora s glavnog ulaza, izrauna njihov skalarni proizvod,
ispie dobijeni rezultat na glavnom izlazu i ponavlja prethodne korake sve dok ne dobije signal za zavretak rada programa. Program treba da je pogodan za skretanje glavnog ulaza na datoteku.

// skalpro.c - Skalarni proizvod dva vektora.


0 1 2

niz: a b c d e x d e
kao da nema

b) posle obrade

// reduk.c - Izostavljanje elemenata niza na osnovu maske.


void redukcija(int niz[], const char maska[], int *n) {
int i, j, k; char m;
for (i=j=k=0; i<*n; i++) {
if (i % 8 == 0) m = maska[k++];
Izdvajanje desnog bita:
if (m & 1) niz[j++] = niz[i];
m >>= 1;
7
2 1 0
}
m: x x x x x x x x &
*n = j;
0 0 0 0 0 0 0 1
}
0 0 0 0 0 0 0 x
#include <stdio.h>

Zadatak 0.1

Napisati na jeziku C rekurzivnu funkciju za izraunavanje skalarnog proizvoda dva vektora.

Reenje:

Izostavljanje odreenih elemenata:


i:
Elementi se ispituju redom (indeks
0 1 2
n-1
i). Ako i-ti element treba da ostane, niz: x a b c x x d e
premeta se na j-to mesto.
Nova duina niza je zavrna vreda) pre obrade
nost indeksa j.

int main() {
enum {N = 120};
while (1) {
printf("n? "); int n; scanf("%d", &n);
if (n<=0 || n>N) break;
printf("niz? "); int niz[120];
for (int i=0; i<n; scanf("%d", &niz[i++]));
printf("maska? "); char maska[(N+7)/8];
for (int i=0; i<(n+7)/8; i++) {
int m; scanf("%x", &m); maska[i] = m;
}
redukcija(niz, maska, &n);
printf("niz=");
for (int i=0; i<n;
printf(" %d", niz[i++]));
putchar('\n');
}
}

Rekurzivno izraunavanje skalarnog proizvoda dva vektora

double skal_pro(const double *a, const double *b, int n) {


return n ? (*a) * (*b) + skal_pro(a+1, b+1, n-1) : 0;
}
#include <stdio.h>
int main() {
int n;
while (scanf("%i", &n) != EOF) {
double a[100];
for (int i=0; i<n; scanf("%lf", &a[i++]));
double b[100];
for (int i=0; i<n; scanf("%lf", &b[i++]));
printf("%g\n", skal_pro(a,b,n));
}
}
sklapro.pod
5
1 2 3 4 5
5 4 3 2 1
4
% skalpro <skalpro.pod >skalpro.rez

% reduk
n? 11
niz? 1 2 3 4 5 6 7
maska? b5 4 1011 0101
niz= 1 3 5 6 8 1
n? 8
niz? 1 2 3 4 5 6 7
maska? ff
niz= 1 2 3 4 5 6 7
n? 5
niz? 1 2 3 4 5
maska? 0
niz=
n? 0

skalpro.rez
35
3
8 9 0 1
0000 0100

8
8

0 Pripremni zadaci

0 Pripremni zadaci

Zadatak 0.2

10

Zadatak 0.3

11

Presek dva skupa u dinamikoj zoni memorije

Zadatak 0.4

Obrtanje redosleda elemenata jednostruko spregnute liste

Skup realnih brojeva predstavlja se pomou strukture od dva lana koji su broj elemenata skupa i pokaziva na niz u dinamikoj zoni memorije koji sadri same elemente skupa. Napisati na jeziku C funkciju za
nalaenje preseka dva takva skupa.

Niz realnih brojeva predstavlja se u obliku jednostruko spregnute liste. Napisati na jeziku C funkciju za
obrtanje redosleda elemenata jednog takvog niza (liste), tj. za zamenu prvog elementa s poslednjim, drugog s pretposlednjim itd.

Napisati na jeziku C program koji proita dva skupa realnih brojeva, pronalazi njihov presek, ispisuje dobijeni rezultat i ponavlja prethodne korake sve dok za broj elemenata skupa ne proita negativnu vrednost.

Napisati na jeziku C program kojim se obrauje proizvoljan broj nizova brojeva pomou prethodne funkcije i ispisuju dobijeni rezultati na glavnom izlazu. Na raspolaganju stoje gotove funkcije za itanje niza
brojeva uz formiranje liste i za brisanje liste. Program treba da zavri s radom kada se proita prazan niz s
glavnog ulaza.

Reenje:
Reenje:
// presek.c - Presek dva skupa.

(2)

(2)

niz:

#include <stdio.h>
#include <stdlib.h>

(3)

NULL

(4)

5
(1)

(3)

(2)

2
(4)

(1)

(3)

NULL

typedef struct { int vel; double *niz; } Skup;

pret:

Skup presek(Skup s1, Skup s2) {


int vel = (s1.vel<s2.vel ? s1.vel : s2.vel);
double *niz = malloc(vel*sizeof(double));
int k = 0;
for (int i=0; i<s1.vel; i++) {
int j = 0; while (j<s2.vel && s2.niz[j]!=s1.niz[i]) j++;
if (j < s2.vel) niz[k++] = s2.niz[j];
}
Skup s = {k, realloc(niz, k*sizeof(double))};
return s;
}

a) na poetku liste

sled:

pret:

tek:

sled:

pret:

b) unutar liste

NULL

NULL

(4)

(1)

tek:

NULL

sled:

c) na kraju liste

// obrni.c Obrtanje redosleda elemenata liste.


#include <stdio.h>
typedef struct elem { float broj; struct elem *sled; } Elem;

int main() {
while (1) {
Skup s1; scanf("%d", &s1.vel);
if (s1.vel < 0) break;
s1.niz = malloc(s1.vel*sizeof(double));
for (int i=0; i<s1.vel; scanf("%lf",&s1.niz[i++]));
Skup s2; scanf("%d", &s2.vel);
if (s2.vel < 0) break;
s2.niz = malloc(s2.vel*sizeof(double));
for (int i=0; i<s2.vel; scanf("%lf",&s2.niz[i++]));
Skup s = presek(s1, s2);
for (int i=0; i<s.vel; printf("%lf ", s.niz[i++])); putchar('\n');
free(s1.niz); free(s2.niz); free(s.niz);
}
}
presek.pod
4
1 2 3
5
3 4 5
6
9 3 5
4
6 2 8
-1

tek:

Elem *obrni(Elem *niz) {


Elem *tek = niz, *pret = NULL, *sled;
while (tek) { sled = tek->sled; tek->sled = pret; pret = tek; tek = sled;
}
return pret;
}
Elem *citaj_niz(void);
void brisi_niz(Elem *);
int main() {
Elem *niz;
while ((niz = citaj_niz()) != NULL) {
niz = obrni(niz);
for (Elem *tek=niz; tek; tek=tek->sled) printf("%g ", tek->broj);
putchar('\n');
brisi_niz(niz);
}
}

4
6 7
1 2 8
5

% presek <presek.pod
3.000000 4.000000
5.000000 2.000000 8.000000
Zadatak 0.3

0 Pripremni zadaci

0 Pripremni zadaci

Zadatak 0.4

12

1 Proirenja jezika C

Zadatak 0.4

0 Pripremni zadaci

13

14

15

Zadatak 1.1

Ispisivanje pozdrava

Zadatak 1.2

Napisati na jeziku C++ program koji ispisuje tekst na glavnom izlazu raunara.

Izraunavanje zbira niza brojeva

Napisati na jeziku C++ program za izraunavanje zbira elemenata niza celih brojeva. Program treba da
obrauje vie kompleta podataka.

Reenje:

Reenje:

// pozdrav.C - Ispisivanje pozdrava.


#include <iostream>
using namespace std;

// zbir.C - Zbir niza celih brojeva.


#include <iostream>
using namespace std;

int main() {
cout << "Pozdrav svima!" << endl;
return 0;
}

int main() {
const int DUZ = 100;

Obrada programa:
1) pod UNIX-om (Linux na PC-u)
%
%
%
%
%

vi imeprog.C
CC imeprog.C -o imeprog
CC imeprog.C -lm -o imeprog
imeprog
imeprog <podaci >rezult

1.
Unos izvornog teksta
2+3. Prevoenje i povezivanje
- ako se koriste matematike funkcije
4.
Izvravanje
- skretanjem glavnog ulaza i izlaza

% vi pozdrav.C
% CC pozdrav.C -o pozdrav
% pozdrav
Pozdrav svima!

while (true) {
cout << "\nDuzina niza? ";
int n; cin >> n;
if (n <= 0 || n > DUZ) break;
int a[DUZ]; cout << "Elementi niza? ";
for (int i=0; i<n; cin >> a[i++]);
int s = 0;
for (int i=0; i<n; s+=a[i++]);
cout << "Zbir elemenata: " << s << endl;
}
return 0;

% CC zbir.C o zbir
% zbir

2) u programskom okruenju Visual Studio .Net:

Duzina niza? 8
Elementi niza? 1 2 3 4 5 6 7 8
Zbir elemenata: 36
Duzina niza? 0

Zadatak 1.1

1 Proirenja jezika C

1 Proirenja jezika C

Zadatak 1.2

16

Zadatak 1.3

17

Ureivanje dinamikog niza brojeva

Zadatak 1.4

Napisati na jeziku C++ program za ureivanje dinamikog niza celih brojeva. Program treba da obrauje
vie kompleta podataka.

Obrada jednostruko spregnute liste brojeva

Napisati na jeziku C++ funkcije za itanje, ispisivanje i unitavanje jednostruko spregnute liste celih brojeva.
Napisati na jeziku C++ glavnu funkciju za ispitivanje prethodnih funkcija.

Reenje:
Reenje:

i:
+

a:

0 1 2

lst:

NULL

// lista1.C - Obrada jednostruko spregnute liste.

n-1

#include <iostream>
using namespace std;

b:

// uredi1.C - Ureivanje dinamikog niza celih brojeva.

struct Elem { int broj; Elem* sled; };

#include <iostream>
using namespace std;

Elem* citaj() {
// Stvaranje liste itajui.
Elem *lst = nullptr, *tek = nullptr;
while (true) {
int broj; cin >> broj;
if (broj == 9999) break;
Elem* novi = new Elem;
novi->broj = broj; novi->sled = nullptr;
tek = (lst==nullptr ? lst : tek->sled) = novi;
}
return lst;
}

int main() {
while (true) {
int n; cout << "Duzina niza? "; cin >> n;
if (n <= 0) break;
int* a = new int [n];
cout << "Pocetni niz? ";
for (int i=0; i<n; cin >> a[i++]);
for (int i=0; i<n-1; i++) {
int& b = a[i];
// b je u stvari a[i].
for (int j=i+1; j<n; j++)
if (a[j]<b) { int c=b; b=a[j]; a[j]=c; }
}
cout << "Uredjeni niz: ";
for (int i=0; i<n; cout << a[i++] << ' ');
cout << endl;
delete [] a;
}
}
% uredi1
Duzina niza?
Pocetni niz?
Uredjeni niz:
Duzina niza?

void pisi(Elem* lst) { // Ispisivanje liste.


while (lst) {
cout << lst->broj << ' '; lst = lst -> sled;
}
}

tek:
lst:

(2)
NULL

novi:

NULL

(3) (6)
NULL (5)

(9)

(1) (4)

(8)

NULL

(7)

NULL

lst:

void brisi(Elem* lst) { // Unitavanje liste.


while (lst) { Elem* stari = lst; lst = lst->sled; delete stari; }
}
(2)
lst:
(3)
int main() {
// Ispitivanje funkcija.
2
3
4
while (true) {
(1)
Elem* lista;
stari:
cout << "\nLista? ";
if ((lista = citaj()) == nullptr) break;
cout << "Procitano: "; pisi(lista); cout << endl;
brisi(lista);
}
}

10
2 0 3 8 7 1 9 4 6 5
0 1 2 3 4 5 6 7 8 9
0

NULL

NULL

% lista1
Lista? 1 2 3 4 5 6 7 8 9 9999
Procitano: 1 2 3 4 5 6 7 8 9
Lista? 9999

Zadatak 1.3

1 Proirenja jezika C

1 Proirenja jezika C

Zadatak 1.4

18

19

Zadatak 1.5

// podelat.C - Ispitivanje funkcije za ureivanje niza metodom podele.

Ureivanje niza brojeva metodom podele

Napisati na jeziku C++ funkciju za ureivanje niza celih brojeva metodom podele (quick sort).
Napisati na jeziku C++ program za ispitivanje prethodne funkcije.

#include <stdlib.h>
#include <iostream>
using namespace std;
void uredi(int[], int);

Reenje:
Niz se podeli oko elementa i tako da levo svi brojevi budu ai, a desno svi budu ai. Levi i
desni deo niza ureuju se nezavisno.
n
i

a:

n-i-1

0 1 2

n-1

ai

ai

i:

Podela se pravi premetanjem elemenata veih od an-1 s poetka niza prema kraju, a elemenata manjih od an-1 skraja prema poetku. Na kraju, an-1 se stavi negde u sredinu niza.
a:

n-1

0 1 2

i:

an-1

an-1

int main() {
while (true) {
int n; cout << "\n\nDuzina niza? "; cin >> n;
if (n <= 0) break;
int* a = new int [n];
cout << "\nPocetni niz:\n\n";
for (int i=0; i<n; i++)
cout << (a[i] = (int)(rand() / (RAND_MAX + 1.) * 10))
<< ((i%30==29 || i==n-1) ? '\n' : ' ');
uredi(a, n);
cout << "\nUredjeni niz:\n\n";
for (int i=0; i<n; i++)
cout << a[i] << ((i%30==29 || i==n-1) ? '\n' : ' ');
delete [] a;
}
}
% podelat

j:

Duzina niza? 97
// podela.C - Ureivanje niza brojeva metodom podele (quick sort).
inline void zameni(int& x, int& y)
{ int z = x; x = y; y = z; }

0
5
8
4

static int podeli(int a[], int n) {


int& b = a[n-1], i = -1, j = n-1;
while (i < j ) {
do i++; while (a[i] < b);
do j--; while (j>=0 && a[j]>b);
zameni(a[i], (i<j) ? a[j] : b);
}
return i;
}

3
5
2
5

0
7
3
2

3
1
4
1

2
4
2
7

5
1
4
6

1 7 9 2 4 1 6 5 0 1 8 6 7 8 9 2 4 9 8 9 8 4 6 6
6 4 4 5 3 8 2 1 4 6 1 5 6 6 0 7 2 4 3 3 5 6 2 1
0 4 9 0 4 0 0 2 9 3 4 1 1 2 2 7 8 9 7 4 5 0 1 4
8

Uredjeni niz:
0
2
5
9

void uredi(int a[], int n) {


if (n > 1) {
int i = podeli(a, n);
uredi(a, i);
uredi(a+i+1, n-i-1);
}
}

Zadatak 1.5

Pocetni niz:

0
2
5
9

0
2
5
9

0
3
5
9

0
3
5
9

0
3
6
9

0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2
3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5
6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8
9

Duzina niza? 0

1 Proirenja jezika C

1 Proirenja jezika C

Zadatak 1.5

20

21

Zadatak 1.6

Izostavljanje suvinih razmaka meu reima

Zadatak 1.7

Ureivanje imena gradova u dinamikoj matrici

Napisati na jeziku C++ program kojim se tekst s glavnog ulaza raunara prepisuje na glavni izlaz raunara uz razdvajanje rei sa po jednim znakom razmaka. Na ulazu rei su razdvojene proizvoljnim brojem
znakova razmaka i/ili tabulacije. Tekst se zavrava signalom za kraj datoteke. Raspodela rei u redove
treba da se ouva.

Napisati program na jeziku C++ za itanje niza imena gradova uz njihovo ureivanje po abecednom redu
i ispisivanje rezultata. Iz svakog reda treba da se ita po jedno ime sve dok se ne proita prazan red. Niz
imena smestiti u dinamiku zonu memorije.

Reenje:

a) U stilu jezika C:
// gradovi1.C - Ureivanje imena
//
gradova smetenih u dina//
miku matricu (u stilu C).

// razmak.C - Izostavljanje suvinih razmaka meu reima.


#include <iostream>
using namespace std;

#include <string.h>
#include <iostream>
using namespace std;

int main() {
int znak; bool ima = true;

Reenje:

while ((znak = cin.get()) != EOF)


// while (cin.get(znak))
if (znak != ' ' && znak != '\t')
{ cout.put(znak); ima = znak == '\n'; }
else if (!ima) { cout.put(' '); ima = true; }

razmak.pod
Ova
linija sadrzi
suvisne znakove razmaka.
U ovoj liniji nema suvisnih znakova razmaka.
===
===
===
===
===
===
===
===
% razmak <razmak.pod
Ova linija sadrzi suvisne znakove razmaka.
U ovoj liniji nema suvisnih znakova razmaka.
=== === === === === === === ===

0 1 2 3

br_grad

0
1
2
3

i:

b e o g r a d \0
t r s t e n i k \0
s u b o t i c a \0
b o r \0
l e s k o v a c \0

MAX_GRAD

p i r o t \0

grad:

const int MAX_GRAD = 100;


const int MAX_DUZ = 30;
int main() {

// itanje i obrada pojedinanih imena:


cout << "\nNeuredjeni niz imena gradova:\n\n";
char** gradovi = new char* [MAX_GRAD];
int br_grad=0;
do {
char* grad = new char [MAX_DUZ];
cin.getline(grad,MAX_DUZ); // itanje sledeeg imena.
int duz = strlen(grad);
// Kraj ako je duina imena nula:
if (!duz) { delete [] grad; break; }
char* pom = new char [duz+1];
strcpy(pom, grad);
delete [] grad; grad = pom;
cout << grad << endl;

// Skraivanje niza.

// Nastavak rada ako ima jo


//
slobodnih vrsta u matrici:
} while (++br_grad < MAX_GRAD);
// Skraivanje niza pokazivaa:
char** pom = new char* [br_grad];
for (int i=0; i<br_grad; i++)
pom[i] = gradovi[i];
delete [] gradovi; gradovi = pom;

1 Proirenja jezika C

1 Proirenja jezika C

gradovi.pod
beograd
trstenik
subotica
bor
leskovac
pirot

// Ispisivanje imena.

// Uvrtavanje novog imena


//
u ureeni niz starih imena:
int i;
for (i=br_grad-1; i>=0; i--)
if (strcmp(gradovi[i], grad) > 0)
gradovi[i+1] = gradovi[i];
else break;
gradovi[i+1] = grad;

Zadatak 1.6

MAX_DUZ

gradovi:

% gradovi1 <gradovi.pod
Neuredjeni niz imena gradova:
beograd
trstenik
subotica
bor
leskovac
pirot
Uredjeni niz imena gradova:
beograd
bor
leskovac
pirot
subotica
trstenik

Zadatak 1.7

22

23

// Ispisivanje ureenog niza imena:


cout << "\nUredjeni niz imena gradova:\n\n";
for (int i=0; i<br_grad; cout<<gradovi[i++]<<endl);

Zadatak 1.8

Napisati na jeziku C++ funkcije za pretvaranje pravouglih koordinata u ravni u polarne koordinate korienjem pokazivaa i upuivaa.

// Unitavanje matrice.
for (int i=0; i<br_grad; delete [] gradovi[i++]);
delete [] gradovi;

Napisati na jeziku C++ glavnu funkciju za ispitivanje prethodnih funkcija.


Reenje:

b) U stilu jezika C++:


// gradovi2.C - Uredivanje imena gradova smetenih u dinamiki niz niski
//
(u stilu C++).
#include <string>
#include <iostream>
using namespace std;

int main() {
// itanje i obrada pojedinanih imena:
cout << "\nNeuredjeni niz imena gradova:\n\n";
string* gradovi = new string [MAX_GRAD];
int br_grad=0;
do {
string grad;
getline(cin, grad);
// itanje sledeeg imena.

#include <math.h>

// Pomou upuivaa.
void polar(double x, double y, double& r, double& fi) {
r = sqrt(x*x + y*y);
fi = (x==0 && y==0) ? 0 : atan2(y, x);
}
#include <iostream>
using namespace std;
int main() {
while (true) {
double x, y; cout << "\nx,y? "; cin >> x >> y;
if (x == 1e38) break;
double r, fi;
polar(x, y, &r, &fi);
cout << "r,fi: " << r << ' ' << fi << endl;
polar(x, y, r, fi);
cout << "r,fi: " << r << ' ' << fi << endl;
}
}

// Kraj ako je prazan red:


if (grad == "") break;
// Ispisivanje imena.

// Uvrtavanje novog imena u ureeni niz starih imena:


int i;
for (i=br_grad-1; i>=0; i--)
if (gradovi[i] > grad)
gradovi[i+1] = gradovi[i];
else break;
gradovi[i+1] = grad;

% polar

// Nastavak rada ako ima jo slobodnih mesta u nizu:


} while (++br_grad < MAX_GRAD);

x,y? 1 1
r,fi: 1.41421 0.785398
r,fi: 1.41421 0.785398

// Skraivanje niza:
string* pom = new string [br_grad];
for (int i=0; i<br_grad; i++)
pom[i] = gradovi[i];
delete [] gradovi; gradovi = pom;

x,y? -3 4
r,fi: 5 2.2143
r,fi: 5 2.2143

// Ispisivanje ureenog niza imena:


cout << "\nUredjeni niz imena gradova:\n\n";
for (int i=0; i<br_grad; cout<<gradovi[i++]<<endl);

// polar.C Odreivanje polarnih koordinata take.

// Pomou pokazivaa.
void polar(double x, double y, double* r, double* fi) {
*r = sqrt(x*x + y*y);
*fi = (x==0 && y==0) ? 0 : atan2(y, x);
}

const int MAX_GRAD = 100;

cout << grad << endl;

Odreivanje polarnih koordinata take

x,y?

1e38 0

// Unitavanje niza.
delete [] gradovi;

Zadatak 1.7

1 Proirenja jezika C

1 Proirenja jezika C

Zadatak 1.8

24

Zadatak 1.9

25

Izraunavanje povrine trougla

Zadatak 1.10 Paket funkcija za obradu redova brojeva neogranienog kapaciteta

Napisati na jeziku C++ funkcije za izraunavanje povrine opteg, jednakokrakog i jednakostraninog


trougla koji je zadat duinama stranica.

Red celih brojeva neogranienog kapaciteta predstavlja se pomou strukture koja sadri pokazivae na
poetak i na kraj reda. Napisati na jeziku C++ paket funkcija za obradu redova celih brojeva.

Napisati na jeziku C++ glavnu funkciju za ispitivanje prethodnih funkcija.

Napisati na jeziku C++ program za ispitivanje prethodnih funkcija.

Reenje:

Reenje:

// trougao1.C Izraunavanje povrine trougla.

// red1.h - Deklaracija paketa za obradu


//
redova celih brojeva.

#include <math.h>
#include <iostream>
using namespace std;

struct Elem { int broj; Elem* sled; };


struct Red { Elem *prvi, *posl; };

// Jednakokraki trugao.
inline double P(double a, double b) { return P(a, b, b); }

prvi:

NULL

:posl

prazan: prvi=posl=NULL
pun:
nikada

// red1.C - Definicije paketa za obradu redova celih brojeva.

// Jednakostranini trougao.
inline double P(double a) { return P(a, a, a); }

#include "red1.h"
#include <stdlib.h>
#include <iostream>
using namespace std;

// Glavna funkcija.
int main() {
while (true) {
cout << "Vrsta (1, 2, 3, 0)? "; int k; cin >> k;
if (k<1 || k>3) break;
double a, b, c, s;
switch (k) {
case 1: cout << "a? ";
cin >> a;
s = P(a);
break;
case 2: cout << "a,b? ";
cin >> a >> b;
s = P(a, b);
break;
case 3: cout << "a,b,c? "; cin >> a >> b >> c;
s = P(a, b, c); break;
}
if (s > 0) cout << "P= " << s << endl;
else
cout << "Greska!\n";
}
}

Zadatak 3.9

inline Red pravi()


// Stvaranje praznog reda.
{ Red r; r.prvi = r.posl = nullptr; return r; }
inline bool prazan(const Red& r)
// Da li je prazan?
{ return r.prvi == nullptr; }
void dodaj(Red& r, int b);
// Dodavanje broja na kraj reda.
int uzmi(Red& r);
// Uzimanje broja s poetka reda.
int duz(const Red& r);
// Odreivanje duine reda.
void pisi(const Red& r);
// Ispisivanje reda.
void brisi(Red& r);
// Pranjenje reda.

// Opti trougao.
double P(double a, double b, double c) {
if (a>0 && b>0 && c>0 && a+b>c && b+c>a && c+a>b) {
double s = (a + b + c) / 2;
return sqrt(s * (s-a) * (s-b) * (s-c));
} else return -1;
}

% trougao1
Vrsta (1, 2, 3, 0)? 1
a? 2
P= 1.73205
Vrsta (1, 2, 3, 0)? 2
a,b? 1 2
P= 0.968246
Vrsta (1, 2, 3, 0)? 3
a,b,c? 3 4 5
P= 6

void dodaj(Red& r, int b) {


// Dodavanje broja na kraj reda.
Elem* novi = new Elem;
novi->broj = b; novi->sled = nullptr;
if (!r.prvi) r.prvi = novi; else r.posl->sled = novi;
r.posl = novi;
}
int uzmi(Red& r) {
if (!r.prvi) exit(1);
int b = r.prvi->broj;
Elem* stari = r.prvi;
r.prvi = r.prvi->sled;
if (!r.prvi) r.posl = nullptr;
delete stari;
return b;
}

Vrsta (1, 2, 3, 0)? 3


a,b,c? 1 2 4
Greska!
Vrsta (1, 2, 3, 0)? 2
a,b? 2 1
Greska!
Vrsta (1, 2, 3, 0)? 0

// Uzimanje broja s poetka reda.

int duz(const Red& r) {


// Odreivanje duine reda.
int d = 0;
for (Elem* tek=r.prvi; tek; tek=tek->sled) d++;
return d;
}
void pisi(const Red& r) {
// Ispisivanje reda.
for (Elem* tek=r.prvi; tek; tek=tek->sled)
cout << tek->broj << ' ';
}

1 Proirenja jezika C

1 Proirenja jezika C

Zadatak 1.10

26

27

void brisi(Red& r) {
// Pranjenje reda.
while (r.prvi) {
Elem* stari = r.prvi; r.prvi=r.prvi->sled; delete stari;
}
r.posl = nullptr;
}

Zadatak 1.11 Paketi funkcija za obradu taaka, pravougaonika i nizova pravougaonika u ravni
Taka u ravni predstavlja se strukturom koja sadri koordinate take. Napisati na jeziku C++ paket funkcija za obradu taaka koji sadri funkcije za sastavljanje take od njenih koordinata (podrazumevano
(0,0)), itanje take s glavnog ulaza i ispisivanje take na glavnom izlazu.

// red1t.C - Ispitivanje paketa za obradu redova celih brojeva.


#include "red1.h"
#include <iostream>
using namespace std;
int main() {
Red r = pravi();
for (bool dalje=true; dalje; ) {
cout << "\n1 Dodaj broj
4 Pisi red\n"
"2 Uzmi broj
5 Brisi red\n"
"3 Uzmi duzinu
0 Zavrsi\n\n"
"Vas izbor? ";
int izb; cin >> izb;
switch (izb) {
case 1: int b; cout << "Broj? "; cin >> b; dodaj(r, b); break;
case 2: if (!prazan(r)) cout << "Broj= " << uzmi(r) << endl;
else cout << "Red je prazan!\n";
break;
case 3: cout << "Duzina= " << duz(r) << endl; break;
case 4: cout << "Red= "; pisi(r); cout << endl; break;
case 5: brisi(r); break;
case 0: dalje = false; break;
default: cout << "Nedozvoljen izbor!\n"; break;
}
}
}
% red1t
1. Dodaj broj
2. Uzmi broj
3. Uzmi duzinu
Vas izbor? 1
Broj? 1

Vas izbor? 1
Broj? 2

Vas izbor? 1
Broj? 3

4. Pisi red
5. Brisi red
0. Zavrsi

Pravougaonik u ravni s ivicama paralelnim koordinatnim osama predstavlja se strukturom koja sadri dve
take koje ine naspramna temena pravougaonika. Napisati na jeziku C++ paket funkcija za obradu
pravougaonika koji sadri funkcije za sastavljanje pravougaonika na osnovu dva temena (podrazumevano
(0,0) i (1,1)), itanje pravougaonika s glavnog ulaza, ispisivanje pravougaonika na glavnom izlazu i izraunavanje povrine pravougaonika.
Dinamiki niz pravougaonika u ravni predstavlja se strukturom koja sadri duinu niza i pokaziva na
elemente niza. Napisati na jeziku C++ paket funkcija za obradu nizova pravougaonika koji sadri funkcije za sastavljanje praznog niza, itanje niza s glavnog ulaza, ispisivanje niza na glavnom izlazu, unitavanje niza, kopiranje niza i ureivanje niza po povrinama pravougaonika u nizu.
Napisati na jeziku C++ program za ispitivanje prethodnih paketa funkcija.
Reenje:
// tacka1.h - Deklaracije paketa za obradu taaka u ravni.
#include <iostream>
using namespace std;
namespace Geometr {
struct Tacka { double x, y; };
inline void pravi(Tacka& T, double x=0, double y=0) { T.x = x; T.y = y; }
inline void citaj(Tacka& T) { cin >> T.x >> T.y; }
inline void pisi(const Tacka& T)
{ cout << '(' << T.x << ',' << T.y << ')'; }
}

Vas izbor? 4
Red= 1 2 3

Vas izbor? 2
Broj= 1

Vas izbor? 2
Broj= 2

Vas izbor? 2
Broj= 3

Vas izbor? 2
Red je prazan!

Vas izbor? 0

const Tacka ORG = {0, 0}, JED = {1, 1};

// pravoug1.h - Deklaracije paketa za obradu pravougaonika u ravni.


#include "tacka1.h"
#include <iostream>
#include <cmath>
using namespace std;
namespace Geometr {
struct Pravoug { Tacka A, C; };
inline void pravi(Pravoug& p, Tacka A=ORG, Tacka C=JED)
{ p.A = A; p.C = C; }
inline void pravi(Pravoug& p, double xA, double yA, double xC, double yC)
{ pravi(p.A, xA, yA); pravi(p.C, xC,yC); }
inline void citaj(Pravoug& p) { citaj(p.A); citaj(p.C); }
inline void pisi(const Pravoug& p)
{ cout << '['; pisi(p.A); cout <<','; pisi(p.C); cout << ']'; }

Zadatak 1.10

1 Proirenja jezika C

inline double P(const Pravoug& p)


{ return fabs(p.A.x-p.C.x) * fabs(p.A.y-p.C.y); }

1 Proirenja jezika C

Zadatak 1.11

28

29

// nizpravoug.h - Deklaracije paketa za obradu


//
dinamikih nizova pravougaonika u ravni.

// pravoug1t.C - Ispitivanje paketa za obradu pravougaonika u ravni.

#include "pravoug1.h"
#include <iostream>
using namespace std;

#include "nizpravoug.h"
#include <iostream>
using namespace std;
using namespace Geometr;

namespace Geometr {
struct Niz_prav { int n; Pravoug* a; };
inline void pravi(Niz_prav& niz) { niz.n = 0; niz.a = nullptr; }
void citaj(Niz_prav& niz);
void pisi(const Niz_prav& niz);
void brisi(Niz_prav& niz);
void kopiraj(Niz_prav& niz1, const Niz_prav& niz2);
}

void uredi(Niz_prav& niz);

int main() {
while (true) {
Niz_prav niz;
cout << endl; citaj(niz);
if (niz.a == nullptr) break;
uredi(niz);
cout << endl; pisi(niz);
brisi(niz);
}
}
% pravoug1t

// nizpravoug.C - Definicije paketa za obradu


//
dinamikih nizova pravougaonika u ravni.

Duzina niza? 4
Pravoug[0] (xA,yA,xC,yC)?
Pravoug[1] (xA,yA,xC,yC)?
Pravoug[2] (xA,yA,xC,yC)?
Pravoug[3] (xA,yA,xC,yC)?

#include "nizpravoug.h"
void Geometr::citaj(Niz_prav& niz) {
cout << "Duzina niza? "; cin >> niz.n;
if (niz.n > 0) {
niz.a = new Pravoug [niz.n];
for (int i=0; i<niz.n; i++) {
cout << "Pravoug[" << i << "] (xA,yA,xC,yC)? ";
citaj(niz.a[i]);
}
} else { niz.n = 0; niz.a = nullptr; }
}

Pravoug[0]
Pravoug[1]
Pravoug[2]
Pravoug[3]

=
=
=
=

1 1 2 4
0 1 -2 2
0 0 2 -2
-1 -1 -2 -2

[(-1,-1),(-2,-2)] 1
[(0,1),(-2,2)] 2
[(1,1),(2,4)] 3
[(0,0),(2,-2)] 4

Duzina niza? 0

void Geometr::pisi(const Niz_prav& niz) {


for (int i=0; i<niz.n; i++) {
cout << "Pravoug[" << i << "] = "; pisi(niz.a[i]);
cout << ' ' << P(niz.a[i]) << endl;
}
}
void Geometr::brisi(Niz_prav& niz)
{ delete [] niz.a; niz.a = nullptr; niz.n = 0; }
void Geometr::kopiraj(Niz_prav& niz1, const Niz_prav& niz2) {
brisi(niz1);
if (niz2.n > 0) {
niz1.a = new Pravoug [niz1.n = niz2.n];
for (int i=0; i<niz1.n; i++) niz1.a[i] = niz2.a[i];
}
}
void Geometr::uredi(Niz_prav& niz) {
for (int i=0; i<niz.n-1; i++)
for (int j=i+1; j<niz.n; j++)
if (P(niz.a[j]) < P(niz.a[i]))
{ Pravoug p = niz.a[i]; niz.a[i] = niz.a[j]; niz.a[j] = p; }
}

Zadatak 1.11

1 Proirenja jezika C

1 Proirenja jezika C

Zadatak 1.11

30

2 Klase

Zadatak 1.11

1 Proirenja jezika C

31

32

Zadatak 2.1

33

Take u ravni

Zadatak 2.2

Napisati na jeziku C++ klasu taaka u ravni. Predvideti: postavljanje i dohvatanje koordinata, izraunavanje rastojanja do zadate take, itanje take i pisanje take.
Napisati na jeziku C++ program za ispitivanje prethodne klase.
Reenje:
// tacka2.h - Definicija klase taaka u ravni.
class Tacka {
double x, y;
public:
void postavi(double a, double b)
{ x = a; y = b; }
double aps() const { return x; }
double ord() const { return y; }
double rastojanje(Tacka) const;
void citaj();
void pisi() const;
};

// Koordinate.
//
//
//
//
//
//
//

Postavljanje
koordinata.
Apscisa.
Ordinata.
Rastojanje do take.
itanje take.
Pisanje take.

+
+
+
+
+
+

Tacka
x, y
postavi()
aps()
ord()
rastojanje()
citaj()
pisi()

Napisati na jeziku C++ program za ispitivanje prethodne klase.


Reenje:

#include <iostream>
using namespace std;
const double FAKTOR = 3.14159265358979323 / 180;

#include <iostream>
using namespace std;

class Ugao {
double ugao;
// Ugao u radijanima.
public:
// Konstruktori:
Ugao(double u=0)
// - podrazumevani i
{ ugao = u; }
//
konverzije,
Ugao(int stp, int min=0, int sek=0)
// - na osnovu stepeni.
{ ugao = ((sek/60.+min)/60+stp) * FAKTOR; }
double rad() const { return ugao; }
// Radijani.
int stp() const
// Stepeni.
{ return int(ugao / FAKTOR); }
int min() const
// Minuti.
{ return int(ugao / FAKTOR * 60) % 60; }
int sek() const
// Sekunde.
{ return int(ugao / FAKTOR * 3600) % 60; }
void razlozi(int& st, int& mi, int& se) const { // Sva tri dela
st = stp(); mi = min(); se = sek();
//
odjednom.
}
Ugao& dodaj(Ugao u)
// Dodavanje ugla.
{ ugao += u.ugao; return *this; }
Ugao& pomnozi(double a)
// Mnoenje realnim brojem.
{ ugao *= a; return *this; }
void citaj() { cin >> ugao; }
// itanje u radijanima.
void citajStep() {
// itanje u stepenima.
int stp, min, sek; cin >> stp >> min >> sek;
*this = Ugao(stp, min, sek);
}
void pisi() const { cout << ugao; }
// Pisanje u radijanima.
void pisiStep() const {
// Pisanje u stepenima.
cout << '(' << stp() << ':' << min() << ':' << sek() << ')';
}
};

// itanje take.

inline void Tacka::pisi() const


// Pisanje take.
{ cout << '(' << x << ',' << y << ')'; }
// tacka2.C - Definicije metoda klase taaka u ravni.
#include "tacka2.h"
#include <cmath>
using namespace std;
double Tacka::rastojanje(Tacka t) const
// Rastojanje do take.
{ return sqrt(pow(x-t.x,2) + pow(y-t.y,2)); }
// tacka2t.C - Ispitivanje klase taaka u ravni.
#include "tacka2.h"
#include <iostream>
using namespace std;
int main() {
cout << "t1? "; double x, y; cin >> x >> y;
Tacka t1; t1.postavi(x, y);
cout << "t2? "; Tacka t2; t2.citaj();
cout << "t1=(" << t1.aps() << ',' << t1.ord()
<< "), t2="; t2.pisi(); cout << endl;
cout << "Rastojanje=" << t1.rastojanje(t2) << endl;
}
% tacka2t
t1? 1 1
t2? 4 5
t1=(1,1), t2=(4,5)
Rastojanje=5
Zadatak 2.1

Napisati na jeziku C++ klasu uglova. Predvideti:


stvaranje ugla na osnovu zadatog broja radijana (podrazumevano 0),
stvaranje ugla na osnovu zadatog broja stepeni, minuta i sekundi,
dohvatanje veliine ugla u radijanima,
dohvatanje delova ugla (celobrojnih stepeni, minuta i sekundi) odvojeno i odjednom,
dodavanje vrednosti drugog ugla tekuem uglu,
mnoenje ugla realnim brojem, i
itanje ugla s glavnog ulaza i ispisivanje ugla na glavnom izlazu u radijanima i u stepenima.

// ugao.h - Definicija klase uglova.

// Definicije ugraenih metoda izvan klase.

inline void Tacka::citaj()


{ cin >> x >> y; }

Uglovi

2 Klase

2 Klase

Zadatak 2.2

34

35

// ugaot.C - Ispitivanje klase uglova.

Zadatak 2.3

#include "ugao.h"
#include <iostream>
using namespace std;

Redovi brojeva ogranienih kapaciteta

Red je linearna struktura podataka kod kojeg se podaci stavljaju na jednom kraju a uzimaju na drugom
kraju. Moe da bude ogranienog i neogranienog kapaciteta. Napisati na jeziku C++ klasu redova ogranienih kapaciteta za cele brojeve. Predvideti:
stvaranje praznog reda sa zadatim kapacitetom, kopiranjem drugog reda i premetanjem drugog reda,
unitavanje reda,
dodavanje jednog podatka i uzimanje jednog podatka,
ispitivanje da li je red pun i da li je prazan,
pisanje sadraja reda na glavnom izlazu, i
pranjenje reda.

int main() {
Ugao u1, u2;
cout << "Prvi ugao [rad]? "; u1.citaj();
cout << "Drugi ugao [rad]? "; u2.citaj();
Ugao sr = Ugao(u1).dodaj(u2).pomnozi(0.5);
cout << "Srednja vrednost= "; sr.pisi();
cout << ' ';
sr.pisiStep(); cout << endl;
}

Napisati na jeziku C++ interaktivan program za ispitivanje prethodne klase.

% ugaot
Prvi ugao [rad]? 1
Drugi ugao [rad]? 3
Srednja vrednost= 2 (114:35:29)

Reenje:
Red:

3 5 2 1 4 7
prvi

posl

duz
niz:

kap-1

0 1 2

3 5 2 1 4 7

prvi:

prazan:
pun:

duz=0
duz=kap

prvi=posl
prvi=posl

posl:

// red2.h - Definicija klase redova ogranienih kapaciteta.


class Red {
int *niz, kap, duz, prvi, posl;
public:
explicit Red(int k=10);
// Stvaranje praznog reda (nije konverzija).
Red(const Red& rd);
// Stvaranje reda kopiranjem drugog reda.
Red(Red&& rd);
// Stvaranje reda premetanjem drugog reda.
~Red() { delete [] niz; }
// Unitavanje reda.
void stavi(int b);
// Stavljanje broja u red.
int uzmi();
// Uzimanje broja iz reda.
bool prazan() const { return duz == 0; } // Da li je red prazan?
bool pun() const { return duz == kap; } // Da li je red pun?
void pisi() const;
// Pisanje sadraja reda.
void prazni() { duz = prvi = posl = 0; } // Pranjenje reda.
};
// red2.C - Definicije metoda klase redova ogranienih kapaciteta.
#include "red2.h"
#include <iostream>
#include <cstdlib>
using namespace std;
Red::Red(int k) {
niz = new int [kap = k];
duz = prvi = posl = 0;
}

Zadatak 2.2

2 Klase

2 Klase

// Stvaranje praznog reda.

Zadatak 2.3

36

37

Red::Red(const Red& rd) {


// Stvaranje reda kopiranjem drugog reda.
niz = new int [kap = rd.kap];
for (int i=0; i<kap; i++) niz[i] = rd.niz[i];
duz = rd.duz; prvi = rd.prvi; posl = rd.posl;
}
Red::Red(Red&& rd) {
// Stvaranje reda premetanjem drugog reda.
niz = rd.niz;
duz = rd.duz; prvi = rd.prvi; posl = rd.posl;
rd.niz = nullptr;
}
void Red::stavi(int b) {
if (duz == kap) exit(1);
niz[posl++] = b;
if (posl == kap) posl = 0;
duz++;
}

// Stavljanje broja u red.

int Red::uzmi() {
if (duz == 0) exit(2);
int b = niz[prvi++];
if (prvi == kap) prvi = 0;
duz--;
return b;
}

// Uzimanje broja iz reda.

duz
niz:

kap-1

0 1 2

3 5 2 1 4 7

prvi:

duz
niz:

posl:

kap-1

0 1 2

4 7

posl:

3 5 2 1

% red2t

prvi:

1.
2.
3.
4.
5.
0.

void Red::pisi() const {


// Pisanje sadraja reda.
for (int i=0; i<duz; cout<<niz[(prvi+i++)%kap]<<' ');
}

#include "red2.h"
#include <iostream>
using namespace std;

rd:
niz
kap
duz
prvi
posl

Stvaranje reda
Stavljanje podatka u red
Uzimanje podatka iz reda
Ispisivanje sadrzaja reda
Praznjenje reda
Zavrsetak rada

Vas izbor?
Kapacitet?

Vas izbor?
Broj?

Vas izbor?
Broj?

Vas izbor?
Broj?

// red2t.C - Ispitivanje klase redova ogranienih kapacieta.

int main() {
Red* rd = new Red(5); bool kraj = false;
while (!kraj) {
cout << "\n1. Stvaranje reda\n"
"2. Stavljanje podatka u red\n"
"3. Uzimanje podatka iz reda\n"
"4. Ispisivanje sadrzaja reda\n"
"5. Praznjenje reda\n"
"0. Zavrsetak rada\n\n"
"Vas izbor? ";
int izbor; cin >> izbor;

switch (izbor) {
case 1: // Stvaranje novog reda:
cout << "Kapacitet? "; int k; cin >> k;
if (k > 0) { delete rd; rd = new Red(k); }
else cout << "*** Nedozvoljen kapacitet! ***\a\n";
break;
case 2: // Stavljanje podatka u red:
if (!rd->pun()) {
cout << "Broj?
"; int b; cin >> b; rd->stavi(b);
} else cout << "*** Red je pun! ***\a\n";
break;
case 3: // Uzimanje podatka iz reda:
if (!rd->prazan())
cout << "Broj=
" << rd->uzmi() << endl;
else cout << "*** Red je prazan! ***\a\n";
break;
case 4: // Ispisivanje sadraja reda:
cout << "Red=
"; rd->pisi(); cout << endl;
break;
case 5: // Pranjenje reda:
rd->prazni(); break;
case 0: // Zavretak rada:
kraj = true; break;
default: // Pogrean izbor:
cout << "*** Nedozvoljen izbor! ***\a\n"; break;
}

5
0
0
0

1
3
2
1
2
2
2
3

Vas izbor? 2
*** Red je pun! ***

Vas izbor? 4
Red=
1 2 3

Vas izbor? 3
Broj=
1

Vas izbor? 3
Broj=
2

Vas izbor? 3
Broj=
3

Vas izbor? 3
*** Red je prazan! ***

Vas izbor? 55
*** Nedozvoljen izbor! ***

Vas izbor? 0

// red2t2.C - Inicijalizacija reda premetanjem drugog reda.


#include "red2.h"
Red f(Red r) { return r; }
int main() { Red rd = f(Red()); }

Zadatak 2.3

2 Klase

2 Klase

Privremeni objekat tipa Red premeta se u parametar r funkcije f (poziva se Red(Red&&)).


Zadatak 2.3

38

Zadatak 2.4

39

// skup1.C - Definicije metoda klase ureenih skupova.

Ureeni skupovi brojeva

#include "skup1.h"
#include <iostream>
using namespace std;

Napisati na jeziku C++ klasu ureenih skupova realnih brojeva. Predvideti:


stvaranje praznog skupa, skupa koji sadri jedan broj i skupa kao kopiju drugog skupa,
unitavanje skupa,
nalaenje unije, preseka i razlike dva skupa,
itanje skupa s glavnog ulaza,
ispisivanje skupa na glavnom izlazu, i
dohvatanje broja elemenata skupa.

void Skup::kopiraj(const Skup& s) {


niz = new double [vel = s.vel];
for (int i=0; i<vel; i++) niz[i] = s.niz[i];
}

Napisati na jeziku C++ program za ispitivanje prethodne klase.


Reenje:
// skup1.h - Definicija klase ureenih skupova.
class Skup {
int vel; double* niz;
// Veliina i elementi skupa.
void kopiraj(const Skup&);
// Kopiranje u skup.
void premesti(Skup& s)
// Premetanje u skup.
{ vel = s.vel; niz = s.niz; s.niz = nullptr; }
void brisi()
// Oslobaanje memorije.
{ delete [] niz; niz = nullptr; vel = 0; }
public:
Skup() { niz = nullptr; vel = 0; }
// Stvaranje praznog skupa.
Skup(double a) {
// Konverzija broja u skup.
niz = new double [vel = 1];
niz[0] = a;
}
Skup(const Skup& s) { kopiraj(s); }
// Inicijalizacija kopiranjem.
Skup(Skup&& s) { premesti(s); }
// Inicijalizacija premetanjem.
~Skup() { brisi(); }
// Unitavanje skupa.
void unija (const Skup&, const Skup&); // Unija dva skupa.
void presek (const Skup&, const Skup&); // Presek dva skupa.
void razlika(const Skup&, const Skup&); // Razlika dva skupa.
void pisi () const;
// Pisanje skupa.
void citaj();
// itanje skupa.
int velicina() const { return vel; }
// Veliina skupa.
};

// Kopiranje skupa.

void Skup::unija (const Skup& s1, const Skup& s2) { // Unija dva skupa.
Skup s;
s.niz = new double [s1.vel+s2.vel]; s.vel = 0;
for (int i=0, j=0; i<s1.vel || j<s2.vel; )
s.niz[s.vel++] = i==s1.vel
? s2.niz[j++] :
j==s2.vel
? s1.niz[i++] :
s1.niz[i]<s2.niz[j] ? s1.niz[i++] :
s1.niz[i]>s2.niz[j] ? s2.niz[j++] :
(j++, s1.niz[i++]);
brisi(); kopiraj(s);
}
void Skup::presek(const Skup& s1, const Skup& s2) { // Presek dva skupa.
Skup s;
s.niz = new double [s1.vel<s2.vel ? s1.vel : s2.vel]; s.vel = 0;
for (int i=0, j=0; i<s1.vel && j<s2.vel; )
if
(s1.niz[i] < s2.niz[j]) i++;
else if (s1.niz[i] > s2.niz[j]) j++;
else
s.niz[s.vel++] = s1.niz[i++], j++;
brisi(); kopiraj(s);
}
void Skup::razlika(const Skup& s1, const Skup& s2) { // Razlika dva skupa.
Skup s;
s.niz = new double [s1.vel]; s.vel = 0;
for (int i=0, j=0; i<s1.vel; )
if
(j == s2.vel)
s.niz[s.vel++] = s1.niz[i++];
else if (s1.niz[i] < s2.niz[j]) s.niz[s.vel++] = s1.niz[i++];
else if (s1.niz[i] > s2.niz[j]) j++;
else
i++, j++;
brisi(); kopiraj(s);
}
void Skup::pisi() const {
// Pisanje skupa.
cout << '{';
for (int i=0; i<vel; i++) { cout << niz[i]; if (i < vel-1) cout << ','; }
cout << '}';
}
void Skup::citaj() {
// itanje skupa.
brisi();
int vel; cin >> vel;
for (int i=0; i<vel; i++) { double broj; cin>>broj; unija(*this, broj); }
}

Zadatak 2.4

2 Klase

2 Klase

Zadatak 2.4

40

41

// skup1t.C - Ispitivanje klase ureenih skupova.

Zadatak 2.5

#include "skup1.h"
#include <iostream>
using namespace std;

Napisati na jeziku C++ klasu trouglova. Predvideti: ispitivanje da li tri dui mogu biti stranice trougla,
stvaranje trougla, dohvatanje duina stranica, izraunavanje obima i povrine, itanje trougla s glavnog
ulaza i ispisivanje trougla na glavnom izlazu.

int main() {
char jos;
do {
Skup s1; cout << "niz1? "; s1.citaj();
Skup s2; cout << "niz2? "; s2.citaj();
cout << "s1
=";
cout << "s2
=";
Skup s; s.unija (s1, s2); cout << "s1+s2=";
s.presek (s1, s2); cout << "s1*s2=";
s.razlika(s1, s2); cout << "s1-s2=";
cout << "\nJos? "; cin >> jos;
} while (jos=='d' || jos=='D');
}

Napisati na jeziku C++ program koji proita dinamiki niz trouglova, uredi niz po neopadajuem redosledu povrina trouglova i ispie dobijeni rezultat.

s1.pisi();
s2.pisi();
s .pisi();
s .pisi();
s .pisi();

cout
cout
cout
cout
cout

<<
<<
<<
<<
<<

endl;
endl;
endl;
endl;
endl;

Trouglovi u ravni

Reenje:
// trougao2.h - Definicija klase trouglova.
#include <cstdlib>
using namespace std;
class Trougao {
double a, b, c;
// Stranice trougla.
public:
static bool moze(double a, double b, double c) { // Da li su stranice
return a>0 && b>0 && c>0 &&
//
prihvatljive?
a+b>c && b+c>a && c+a>b;
}
Trougao(double aa=1, double bb=1, double cc=1) { // Postavljanje
if (!moze(aa, bb, cc)) exit(1);
//
koordinata.
a = aa; b = bb; c = cc;
}
double dohvA() const { return a; }
// Dohvatanje stranica.
double dohvB() const { return b; }
double dohvC() const { return c; }
double O() const { return a + b + c; }
// Obim trougla.
double P() const;
// Povrina trougla.
bool citaj();
// itanje trougla.
void pisi() const;
// Pisanje trougla.
};

% skup1t
niz1? 4
1 2 3 4
niz2? 5
3 4 5 6 7
s1
={1,2,3,4}
s2
={3,4,5,6,7}
s1+s2={1,2,3,4,5,6,7}
s1*s2={3,4}
s1-s2={1,2}
Jos? d
niz1? 6
9 3 5 1 7 3
niz2? 4
6 2 8 8
s1
={1,3,5,7,9}
s2
={2,6,8}
s1+s2={1,2,3,5,6,7,8,9}
s1*s2={}
s1-s2={1,3,5,7,9}

// trougao2.C - Definicije metoda klase trouglova.

Jos? n

#include "trougao2.h"
#include <iostream>
#include <cmath>
using namespace std;
double Trougao::P() const {
double s = O() / 2;
return sqrt(s * (s-a) * (s-b) * (s-c));
}

// Povrina trougla.

bool Trougao::citaj() {
double aa, bb, cc;
cin >> aa >> bb >> cc;
if (!moze(aa, bb, cc)) return false;
a = aa; b = bb; c = cc;
return true;
}

// itanje trougla.

void Trougao::pisi() const {


// Pisanje trougla.
cout << "Troug(" << a << ',' << b << ',' << c << ')';
}
Zadatak 2.4

2 Klase

2 Klase

Zadatak 2.5

42

43

// trougao2t.C - Ispitivanje klase trouglova.

Zadatak 2.6

#include "trougao2.h"
#include <iostream>
using namespace std;

Napisati na jeziku C++ klasu kvadara iji svi primerci moraju biti u dinamikoj zoni memorije. Ukupna
zapremina svih postojeih kvadara nijednog trenutka ne sme da pree odreenu najveu vrednost.
Predvideti:
postavljanje i dohvatanje vrednosti dozvoljene ukupne zapremine svih kvadara,
dohvatanje trenutne ukupne zapremine svih kvadara,
stvaranje kvadra zadatih duina ivica,
itanje kvadra s glavnog ulaza,
dohvatanje duina ivica kvadra,
izraunavanje zapremine kvadra, i
ispisivanje kvadra na glavnom izlazu.

int main() {
cout << "Broj trouglova? "; int n; cin >> n;
Trougao* niz = new Trougao [n];
for (int i=0; i<n; ) {
cout << i+1 << ". trougao? ";
double a, b, c; cin >> a >> b >> c;
if (Trougao::moze(a,b,c)) niz[i++] = Trougao(a, b, c);
else cout << "*** Neprihvatljive stranice! ***\n";
}
for (int i=0; i<n-1; i++)
for (int j=i+1; j<n; j++)
if (niz[j].P() < niz[i].P())
{ Trougao pom = niz[i]; niz[i] = niz[j]; niz[j] = pom; }
cout << "\nUredjeni niz trouglova:\n";
for (int i=0; i<n; i++) {
cout << i+1 << ": "; niz[i].pisi();
cout << " P=" << niz[i].P() << endl;
}
delete [] niz;
}

Kvadri u dinamikoj zoni memorije

Napisati na jeziku C++ program za ispitivanje prethodne klase.


Reenje:
// kvadar1.h - Definicija klase kvadara.
#include <iostream>
using namespace std;
class Kvadar {
static double Vmax, Vuk;
double a, b, c;

// Dozvoljena i trenutna ukupna zapremina.


// Duine ivica kvadra.

Kvadar(double aa, double bb, double cc) // Konstruktor samo za interne


{ a = aa; b = bb; c = cc; }
//
potrebe.

% trougao2t
Broj trouglova? 5
1. trougao? 1 1 1
2. trougao? 3 4 5
3. trougao? 1 2 2
4. trougao? 1 3 5
*** Neprihvatljive stranice! ***
4. trougao? 2 3 4
5. trougao? 5 6 7

public:
Kvadar(const Kvadar&) = delete;
static bool postaviVmax(double maxV)
if (maxV < Vuk) return false;
Vmax = maxV;
return true;
}

Uredjeni niz trouglova:


1: Troug(1,1,1) P=0.433013
2: Troug(1,2,2) P=0.968246
3: Troug(2,3,4) P=2.90474
4: Troug(3,4,5) P=6
5: Troug(5,6,7) P=14.6969

// Ne sme da se kopira.
{ // Postavljanje maksimalne
//
zapremine.

static double dohvVmax()


{ return Vmax; }

// Dohvatanje maksimalne
//
zapremine.

static double dohvVuk()


{ return Vuk; }

// Dohvatanje trenutne
//
ukupne zapremine.

static Kvadar* pravi(double a, double b, double c) { // Stvaranje


double V = a * b * c;
//
dinamikog kvadra.
if (a<=0 || b<=0 || c<= 0 || Vuk+V>Vmax) return nullptr;
Vuk += V; return new Kvadar(a, b, c);
}
static Kvadar* citaj() {
// itanje kvadra.
double a, b, c; cin >> a >> b >> c;
return pravi(a, b, c);
}
~Kvadar() { Vuk -= a * b * c; }
// Unitavanje kvadra.
double dohvA() const { return a; }
// Dohvatanje duina ivica.
double dohvB() const { return b; }
double dohvC() const { return c; }
double V() const { return a * b * c; }

// Zapremina kvadra.

void pisi() const


// Pisanje kvadra.
{ cout << "kvadar[" << a << ',' << b << ',' << c << ']'; }
};
Zadatak 2.5

2 Klase

2 Klase

Zadatak 2.6

44

45

// kvadar1.C - Definicije statikih polja klase kvadara.

Zadatak 2.7

#include "kvadar1.h"

Napisati na jeziku C++ klasu krugova u ravni koji ne smeju da se preklapaju. Predvideti:
proveravanje da li krug zadatog poluprenika i koordinata centra sme da postoji,
stvaranje kruga zadatog poluprenika i koordinata centra,
unitavanje kruga,
izraunavanje rastojanja najbliih taaka dva kruga,
premetanje kruga na drugo mesto u ravni i pomeranje kruga za odreeni pomak,
ispisivanje kruga na glavnom izlazu, i
ispisivanje svih krugova na glavnom izlazu.

double Kvadar::Vmax = 0, Kvadar::Vuk = 0;


// kvadar1t.C - Ispitivanje klase kvadara.
#include "kvadar1.h"
#include <iostream>
#include <cstdlib>
using namespace std;
int main(int, char* varg[]) {
Kvadar::postaviVmax(atof(varg[1]));

Napisati na jeziku C++ program za ispitivanje prethodne klase.

struct Elem {
// Element liste kvadara.
Kvadar* kvad; Elem* sled;
Elem(Kvadar* kv) { kvad = kv; sled = nullptr; }
~Elem() { delete kvad; }
};

Reenje:
Tacka

// krug1.h - Definicija klase krugova


//
u ravni.

for (char jos='d'; jos=='d' || jos=='D'; cout<<"\nJos? ", cin>>jos) {


Elem *prvi = nullptr, *posl = nullptr;

#include "tacka2.h"
#include <cstdlib>
#include <cmath>
#include <iostream>
using namespace std;

while (true) {
// itanje kvadara i stvaranje liste.
cout << "a,b,c? ";
if (Kvadar* kv = Kvadar::citaj())
posl = (!prvi ? prvi : posl->sled) = new Elem(kv);
else break;
}

Krugovi u ravni koji ne smeju da se preklapaju

cout << "Zapremine:";


// Zapremine proitanih kvadara.
for (Elem* tek=prvi; tek; tek=tek->sled) cout << ' ' << tek->kvad->V();
cout << "\nUkupno: " << Kvadar::dohvVuk() << endl;
// Unitavanje liste kvadara.
while (prvi) { Elem* stari = prvi; prvi = prvi->sled; delete stari; }
cout << "Ukupno posle brisanja: " << Kvadar::dohvVuk() << endl;

% kvadar1t 100
a,b,c? 1 2 3
a,b,c? 2 3 4
a,b,c? 3 4 5
a,b,c? 4 5 6
Zapremine: 6 24 60
Ukupno: 90
Ukupno posle brisanja: 0

Zadatak 2.1

class Krug {
Tacka c; double r;
Krug *pret, *sled;
static Krug* prvi;
Krug() { r = -1; }
Krug(const Krug&) =delete;

//
//
//
//
//
//
//

+
+
+
+
+
+

(Zadatak 2.1)

x, y
postavi()
aps()
ord()
rastojanje()
citaj()
pisi()

-c
1

+
+
+
f
+
+
+
+

Krug
r
pret, sled
prvi
moze()
Krug()
~Krug()
rastojanje()
premesti()
pomeri()
pisi()
pisiSve()

Centar i poluprenik kruga.


Pokazivai na prethodni i na sledei krug.
Poetak zajednike liste svih krugova.
Stvaranje "praznog" kruga:
- SAMO za interne potrebe!
Kopirajui konstruktor:
- NE SME da se pravi kopija!

public:
static bool moze(double r, double x, double y); // Moe li postojati?
Krug(double rr, double x, double y);
// Stvaranje kruga.
~Krug();
// Unitavanje kruga.
friend double rastojanje(const Krug& k1, const Krug& k2);
// Rastojanje dva kruga.
bool premesti(double x, double y);
// Premetanje kruga.
bool pomeri (double dx, double dy);
// Pomeranje kruga.
void pisi() const;
// Pisanje kruga.
static void pisiSve();
// Pisanje svih krugova.
};
// Definicije ugraenih funkcija izvan klase.

Jos? d
a,b,c? 1 1 1
a,b,c? 2 2 2
a,b,c? 3 3 3
a,b,c? 0 0 0
Zapremine: 1 8 27
Ukupno: 36
Ukupno posle brisanja: 0

inline double rastojanje(const Krug& k1, const Krug& k2)


{ return k1.c.rastojanje(k2.c) - k1.r - k2.r; } // Rastojanje dva kruga.
inline void Krug::pisi() const
// Pisanje kruga.
{ cout << "K[" << r << ','; c.pisi(); cout << ']'; }

Jos? n

Zadatak 2.6

2 Klase

2 Klase

Zadatak 2.7

46

47

// krug1.C - Definicije metoda i statikih polja klase krugova.

// krug1t.C - Ispitivanje klase krugova.

#include "krug1.h"

#include "krug1.h"
#include <iostream>
using namespace std;

Krug* Krug::prvi = nullptr;

// Poetak zajednike liste.

bool Krug::moze(double r, double x, double y){ // Moe li postojati?


Krug k; k.r = r; k.c.postavi(x, y);
Krug* tek = prvi;
while (tek && rastojanje(k,*tek)>=0) tek=tek->sled;
k.r = -1;
return tek == nullptr;
}
Krug::Krug(double rr, double x, double y) {
if (!moze(rr, x, y)) exit(1);
r = rr; c.postavi(x, y);
sled = prvi; pret = nullptr;
if (prvi) prvi->pret = this;
prvi = this;
}

// Stvaranje kruga.
null

prvi:
(3)

this:

(1)

null

(2)

null

Krug::~Krug() {
// Unitavanje kruga (izbacivanje iz liste).
if (r > 0) {
(1)
if (pret) pret->sled = sled;
NULL
prvi:
else prvi = sled;
if (sled) sled->pret = pret;
this:
}
}
bool Krug::premesti(double x, double y) {
if (!moze(r, x, y)) return false;
c.postavi(x, y);
return true;
}

NULL

(2)

// Premetanje kruga.

bool Krug::pomeri(double dx, double dy) {


// Pomeranje kruga.
if (!moze(r, c.aps()+dx, c.ord()+dy)) return false;
c.postavi(c.aps()+dx, c.ord()+dy);
return true;
}
void Krug::pisiSve() {
cout << "\nSvi krugovi u memoriji:\n";
for (Krug* tek=prvi; tek; tek=tek->sled)
{ tek->pisi(); cout << endl; }
}

int main() {
char jos;
do {
Krug* krugovi[100]; int n = 0;
while (true) {
cout << "Poluprecnik? "; double r; cin >> r;
if (r <= 0) break;
cout << "Koordinate centra? "; double x, y; cin >> x >> y;
if (Krug::moze(r, x, y)) {
krugovi[n++] = new Krug(r, x, y);
} else cout << "*** Ne moze da se smesti! ***\n\a";
}
Krug::pisiSve();
for (int i=0; i<n; delete krugovi[i++]);
cout << "\nJos? "; cin >> jos;
} while (jos!='N' && jos!='n');
}
% krug1t
Poluprecnik? 1
Koordinate centra? 1 1
Poluprecnik? 2
Koordinate centra? 3 3
*** Ne moze da se smesti! ***
Poluprecnik? 2
Koordinate centra? 4 4
Poluprecnik? 3
Koordinate centra? -1 5
Poluprecnik? 0
Svi krugovi u memoriji:
K[3,(-1,5)]
K[2,(4,4)]
K[1,(1,1)]

// Pisanje svih krugova.

Jos? d
Poluprecnik? 1
Koordinate centra? 1 1
Poluprecnik? 1
Koordinate centra? 3 3
Poluprecnik? 2
Koordinate centra? 4 4
*** Ne moze da se smesti! ***
Poluprecnik? 0
Svi krugovi u memoriji:
K[1,(3,3)]
K[1,(1,1)]
Jos? n

Zadatak 2.7

2 Klase

2 Klase

Zadatak 2.7

48

Zadatak 2.8

49

inline bool Datum::moze(short d, short m, short g)


{ return g>0 && m>0 && m<=12 && d>0 && d<=duz[prestupna(g)][m-1]; }

Kalendarski datumi

Napisati na jeziku C++ klasu kalendarskih datuma. Predvideti:


ispitivanje da li je data godina prestupna,
ispitivanje da li tri cela broja predstavljaju ispravan datum,
stvaranje datuma,
dohvatanje delova datuma,
itanje novog datuma s glavnog ulaza,
pisanje datuma na glavnom izlazu,
odreivanje rednog broja dana u godini poev od 1.1.1. i u toku nedelje u datumu,
dohvatanje broja dana u mesecu u datumu,
dodavanje datumu i oduzimanje od datuma jednog dana i zadatog broja dana,
odreivanje broja dana izmeu dva datuma, i
dohvatanje imena meseca i imena dana datuma.

inline Datum::Datum(short d, short m, short g) {


if (!moze(d, m, g)) exit(1);
dan = d; mes = m; god = g;
}
inline int Datum::danUGod() const
{ return prot[prestupna()][mes-1] + dan; }
inline int Datum::danUNed() const { return(ukDan() + 6) % 7 + 1; }
inline int Datum::duzMes() const { return duz[prestupna()][mes-1]; }
inline long razlika(Datum dat1, Datum dat2)
{ return dat1.ukDan() - dat2.ukDan(); }

Napisati na jeziku C++ program za ispitivanje prethodne klase.

inline string Datum::imeMes() const { return imeM[mes-1]; }

Reenje:

inline string Datum::imeDan() const { return imeD[danUNed()-1]; }

// datum1.h - Definicija klase kalendarskih datuma.


// datum1.C - Definicije statikih polja i metoda
//
klase kalendarskih datuma.

#include <cstdlib>
#include <string>
using namespace std;
class Datum {
static const short duz[][12], // Brojevi dana po mesecima.
prot[][12]; // Protekli dani od poetka godine.
static const string imeD[],
// Imena dana.
imeM[];
// Imena meseci.
short dan, mes, god;
// Delovi datuma.
public:
static bool prestupna(short g);
// Da li je prestupna godina?
bool prestupna() const { return prestupna(god); }
static bool moze(short d, short m, short g); // Da li je ispravan?
Datum(short d, short m, short g);
// Stvaranje datuma.
short dohvDan() const { return dan; }
// Dohvatanje delova datuma.
short dohvMes() const { return mes; }
short dohvGod() const { return god; }
static Datum citaj();
// itanje datuma.
void pisi() const;
// Pisanje datuma.
int danUGod() const;
// Redni broj dana u godini.
long ukDan() const;
// Redni broj dana od 1.1.1.
int danUNed() const;
// Redni broj dana u nedelji.
int duzMes() const;
// Broj dana u mesecu.
void sutra();
// Sledei datum.
void juce();
// Prethodni datum.
void dodaj (unsigned k);
// Dodavanje celog broja.
void oduzmi(unsigned k);
// Oduzimanje celog broja.
friend long razlika(Datum dat1, Datum dat2); // Razlika dva datuma.
string imeDan() const;
// Ime dana.
string imeMes() const;
// Ime meseca.
};
// Definicije metoda koje se ugrauju neposredno u kod.
inline bool Datum::prestupna(short g)
{ return g%4==0 && g%100!=0 || g%400==0; }
Zadatak 2.8

2 Klase

#include "datum1.h"
#include <iostream>
using namespace std;
const short Datum::duz[][12] =
// Brojevi dana po mesecima.
{{31,28,31,30,31,30,31,31,30,31,30,31},
{31,29,31,30,31,30,31,31,30,31,30,31}},
Datum::prot[][12] =
// Brojevi dana od poetka godine.
{{0,31,59,90,120,151,181,212,243,273,304,334},
{0,31,60,91,121,152,182,213,244,274,305,335}};
const string Datum::imeD[] = {"ponedeljak", "utorak", "sreda", "cetvrtak",
"petak", "subota", "nedelja"},
Datum::imeM[] = {"januar", "februar", "mart", "april", "maj",
"jun", "jul", "avgust", "septembar",
"oktobar", "novembar", "decembar"};
Datum Datum::citaj() {
short d, m, g;
while (true) {
cin >> d >> m >> g;
if (moze(d, m, g)) break;
printf("\n*** Neispravan datum, unesite ponovo: ");
}
return Datum(d, m, g);
}
void Datum::pisi() const {
cout << dan/10 << dan%10 << ". " << imeM[mes-1] << ' ' << god << '.';
}
long Datum::ukDan() const {
short g = god - 1;
return g*365L + g/4 - g/100 + g/400 + danUGod();
}

2 Klase

Zadatak 2.8

50

51

void Datum::sutra() {
if (dan < duzMes()) dan++;
else {
dan = 1;
if (mes < 12) mes++;
else { mes = 1; god++; }
}
}

Zadatak 2.9

Liste brojeva

void Datum::juce() {
if (dan > 1) dan--;
else {
if (mes > 1) mes--;
else { mes = 12; god--; }
dan = duzMes();
}
}

Napisati na jeziku C++ klasu listi celih brojeva. Predvideti:


stvaranje prazne liste, liste od jednog broja i liste kao kopiju druge liste,
unitavanje liste,
odreivanje broja elemenata liste,
ispisivanje liste na glavnom izlazu,
dodavanje broja na poetak liste,
dodavanje broja na kraj liste,
itanje liste s glavnog ulaza dodajui brojeve na poetak liste,
itanje liste s glavnog ulaza dodajui brojeve na kraj liste,
umetanje broja u ureenu listu,
pranjenje liste, i
izostavljanje iz liste svakog pojavljivanja datog broja.

void Datum::dodaj (unsigned k) { for (unsigned i=0; i<k; i++) sutra(); }

Napisati na jeziku C++ program za ispitivanje prethodne klase.

void Datum::oduzmi(unsigned k) { for (unsigned i=0; i<k; i++) juce (); }

Reenje:

// datum1t.C - Ispitivanje klase kalendarskih datuma.

1) Iterativno (ciklusima)

#include "datum1.h"
#include <iostream>
using namespace std;

prvi:

null

// lista2.h - Definicija klase listi celih brojeva (iterativno).

int main() {
cout << "Danasnji datum? "; Datum dat1 = Datum::citaj();
cout << "Datum rodjenja? "; Datum dat2 = Datum::citaj();
dat1.pisi();
cout << " je " << dat1.imeDan() << ", "
<< dat1.danUGod() << ". dan u godini.\n"
<< "Rodili ste se u " << dat2.imeDan() << " i imate "
<< razlika(dat1,dat2) << " dana.\n";
}

class Lista {
struct Elem {
// ELEMENT LISTE:
int broj;
// - sadraj,
Elem* sled;
// - pokaziva na sledei element,
Elem(int b, Elem* s=nullptr) // - konstruktor.
{ broj = b; sled = s; }
};
Elem* prvi;
// Pokaziva na poetak liste.
public:
// Konstruktori:
Lista() { prvi = nullptr; }
// - podrazumevani,
Lista(int b)
// - konvertujui,
{ prvi = new Elem(b); }
Lista(const Lista& lst);
// - kopirajui,
Lista(Lista&& lst)
// - premetajui.
{ prvi = lst.prvi; lst.prvi = nullptr; }
~Lista() { prazni(); }
// Destruktor.
int duz() const;
// Broj elemenata liste.
void pisi() const;
// Pisanje liste.
void naPocetak(int b) {
// Dodavanje na
prvi:
3
8
5 null
prvi = new Elem(b, prvi);
//
poetak.
(3)
(2)
(1)
}
9
void naKraj(int b);
// Dodavanje na kraj.
void citaj1(int n);
// itanje liste stavljajui brojeve na poetak.
void citaj2(int n);
// itanje liste stavljajui brojeve na kraj.
void umetni(int b);
// Umetanje u ureenu listu.
void prazni();
// Pranjenje liste.
void izostavi(int b);
// Izostavljanje svakog pojavljivanja.
};

% datum1t
Danasnji datum? 2 9 2014
Datum rodjenja? 12 5 1986
02. septembar 2014. je utorak, 245. dan u godini.
Rodili ste se u ponedeljak i imate 10340 dana.

Zadatak 2.8

Ostvariti prethodnu klasu i pomou rekurzivnih metoda.

2 Klase

2 Klase

Zadatak 2.9

52

53

void Lista::umetni(int b) {
// Umetanje u ureenu listu.
Elem *tek=prvi, *pret=nullptr;
prvi:
2
3
4
5
7
8
while (tek && tek->broj < b)
(3) (2)
(3) (2)
{ pret = tek; tek = tek->sled; }
NULL
1
6
Elem* novi = new Elem(b, tek);
pret: (1)
tek:
pret: (1) tek:
if (!pret) prvi = novi;
else pret->sled = novi;
novi:
novi:
}
a) ispred prvog
b) unutar liste

// lista2.C - Definicije metoda listi celih brojeva (iterativno).


#include "lista2.h"
#include <iostream>
using namespace std;
int Lista::duz() const {
// Broj elemenata liste.
int n = 0;
prvi:
for (Elem* tek=prvi; tek; tek=tek->sled)
3
8
n++;
tek:
return n;
}

null

void Lista::prazni() {
while (prvi) {
Elem* stari = prvi;
prvi = prvi->sled;
delete stari;
}
}

void Lista::pisi() const {


// Pisanje liste.
for (Elem* tek=prvi; tek; tek=tek->sled)
cout << tek->broj << ' ';
}
void Lista::naKraj(int b) {
// Dodavanje na kraj.
Elem* novi = new Elem(b);
if (!prvi) prvi = novi;
prvi:
3
else {
tek:
Elem* tek = prvi;
while (tek->sled) tek = tek->sled;
tek->sled = novi;
}
}

(2)
null

null

(1)

:novi

void Lista::citaj1(int n) { // itanje stavljajui brojeve na poetak.


prazni();
null :prvi
(9)
for (int i=0; i<n; i++) {
(6)
(3)
int b; cin >> b;
(2)
(5)
(8)
null
3
2
1
prvi = new Elem(b, prvi);
(7)
(1)
(4)
}
}
void Lista::citaj2(int n) { // itanje stavljajui brojeve na kraj.
prazni(); Elem* posl = nullptr;
posl: null
for (int i=0; i<n; i++) {
(3) (6)
int b; cin >> b;
null (2)
null (5)
prvi:
1
2
Elem* novi = new Elem(b);
(1) (4)
if (!prvi) prvi = novi; else posl->sled = novi;
novi:
posl = novi;
}
}

(9)
null (8)

null

(7)

Lista::Lista(const Lista& lst) { // Kopirajui konstruktor.


prvi = nullptr;
for (Elem *tek=lst.prvi, *posl=nullptr; tek; tek=tek->sled) {
Elem* novi = new Elem(tek->broj);
if (!prvi) prvi = novi; else posl->sled = novi;
posl = novi;
}
}

Zadatak 2.9

2 Klase

null

// Pranjeje liste.
prvi:

(2)

(3)

stari:

null

(1)

void Lista::izostavi(int b) {
// Izostavljanje svakog pojavljivanja.
Elem *tek = prvi, *pret = nullptr;
(3)
(3)
(4)
(4)
while (tek)
x
x
prvi:
if (tek->broj != b) {
pret = tek; tek = tek->sled;
(1)
(1)
(2)
(2)
NULL
} else {
pret:
tek:
pret:
tek:
Elem* stari = tek;
tek = tek->sled;
stari:
stari:
if (!pret) prvi = tek;
a) prvog u listi
b) unutar liste
else pret->sled = tek;
delete stari;
}
}

null

// lista2t.C - Ispitivanje klase listi celih brojeva.


#include "lista2.h"
#include <iostream>
using namespace std;
int main() {
Lista lst; bool kraj = false;
while (!kraj) {
cout << "\n1. Dodavanje broja na pocetak liste\n"
"2. Dodavanje broja na kraj liste\n"
"3. Umetanje broja u uredjenu listu\n"
"4. Izostavljanje broja iz liste\n"
"5. Praznjenje liste\n"
"6. Citanje uz obrtanje redosleda brojeva\n"
"7. Citanje uz cuvanje redosleda brojeva\n"
"8. Odredjivanje duzine liste\n"
"9. Ispisivanje liste\n"
"0. Zavrsetak rada\n\n"
"Vas izbor? ";
int izbor; cin >> izbor;

2 Klase

Zadatak 2.9

54

55

switch (izbor) {
case 1: case 2: case 3: case 4:
cout << "Broj?
"; int broj; cin >> broj;
switch (izbor) {
case 1:
// Dodavanje broja na poetak liste:
lst.naPocetak(broj); break;
case 2:
// Dodavanje broja na kraj liste:
lst.naKraj(broj);
break;
case 3:
// Umetanje broja u ureenu listu:
lst.umetni(broj);
break;
case 4:
// Izostavljanje broja iz liste:
lst.izostavi(broj); break;
} break;
case 5:
// Pranjenje liste:
lst.prazni(); break;
case 6: case 7: // itanje liste:
cout << "Duzina?
"; int n; cin >> n;
cout << "Elementi? ";
switch(izbor) {
case 6:
// - uz obrtanje redosleda brojeva:
lst.citaj1(n); break;
case 7:
// - uz uvanje redosleda brojeva:
lst.citaj2(n); break;
} break;
case 8:
// Odreivanje duine liste:
cout << "Duzina=
" << lst.duz() << endl; break;
case 9:
// Ispisivanje liste:
cout << "Lista=
"; lst.pisi(); cout << endl; break;
case 0:
// Zavretak rada:
kraj = true; break;
default:
// Pogrean izbor:
cout << "*** Nedozvoljen izbor! ***\a\n"; break;
}

% lista2t
1.
2.
3.
4.
5.
6.
7.
8.
9.
0.

Vas izbor?
Broj?

Vas izbor?
Broj?

Vas izbor?
Broj?

Vas izbor?
Broj?

Vas izbor?
Broj?

Dodavanje broja na pocetak liste


Dodavanje broja na kraj liste
Umetanje broja u uredjenu listu
Izostavljanje broja iz liste
Brisanje svih elemenata liste
Citanje uz obrtanje redosleda brojeva
Citanje uz cuvanje redosleda brojeva
Odredjivanje duzine liste
Ispisivanje liste
Zavrsetak rada

Vas izbor?
Broj?

Vas izbor?
Broj?

Vas izbor?
Broj?

Zadatak 2.9

1
1
1
2
1
3

Vas izbor?
Broj?

Vas izbor?
Broj?

Vas izbor?
Broj?

Vas izbor?
Duzina=

Vas izbor?
Lista=

Vas izbor?

Vas izbor?
Broj?

3
2
3
6
3
4
3
1
3
5

Vas izbor?
Broj?

Vas izbor?
Lista=

Vas izbor?
Broj?

Vas izbor?
Lista=

Vas izbor?
Duzina?
Elementi?

3
2
9
1 2 2 4 5 5 6
4
5
9
1 2 2 4 6
6
5
1 2 3 4 5

Vas izbor? 9
Lista=
5 4 3 2 1

Vas izbor? 7
Duzina?
5
Elementi? 1 2 3 4 5

Vas izbor? 9
Lista=
1 2 3 4 5

Vas izbor? 11
*** Nedozvoljen izbor! ***

Vas izbor? 0

2) Rekurzivno
lst:
// lista3.h - Definicija klase listi
//
celih brojeva (rekurzivno).
#include <iostream>
using namespace std;

2
4
2
5
2
6
8
6
9
3 2 1 4 5 6
5
3
5

2 Klase

glava

rep

(jedan element)

(lista, moda
prazna)

null

class Lista {
struct Elem {
// Element liste:
int broj;
// - sadraj,
Elem* sled;
// - pokaziva na sledei,
Elem(int b, Elem* s=nullptr) // - konstruktor.
{ broj = b; sled = s; }
};
Elem* prvi;
// Pokaziva na poetak liste.
public:
// Konstruktori:
Lista() { prvi = nullptr; }
// - podrazumevani,
Lista(int b)
// - konvertujui,
{ prvi = new Elem(b); }
Lista(const Lista& lst)
// - kopirajui,
{ prvi = nullptr; kopiraj(lst.prvi); }
Lista(Lista&& lst)
// - premetajui.
{ prvi = lst.prvi; lst.prvi = nullptr; }
~Lista() { brisi(prvi); }
// Destruktor.
int duz() const
// Broj elemenata liste.
{ return duz(prvi); }
void pisi() const
// Ispisivanje liste.
{ pisi(prvi); }
void naPocetak(int b)
// Dodavanje na poetak.
{ prvi = new Elem(b, prvi); }
void naKraj(int b)
// Dodavanje na kraj.
{ naKraj(prvi, b); }
void citaj1(int n) // itanje liste stavljajui brojeve na poetak.
{ prazni(); citaj1(prvi, n); }
void citaj2(int n) // itanje liste stavljajui brojeve na kraj.
{ prazni(); citaj2(prvi, n); }
void umetni(int b)
// Umetanje u ureenu listu.
{ umetni(prvi, b); }
void prazni()
// Pranjenje liste.
{ brisi(prvi); }
void izostavi(int b)
// Izostavljanje svakog pojavljivanja.
{ izostavi(prvi, b); }
2 Klase

Zadatak 2.9

56

57

private:
// POMONE REKURZIVNE METODE:
static Elem* kopiraj(Elem* lst) {
// Kopiranje liste.
return lst ? new Elem(lst->broj, kopiraj(lst->sled)) : nullptr;
}

Nova glava + kopija repa.

static int duz(Elem* lst)


// Broj elemenata liste.
1 + duina repa.
{ return lst ? 1+duz(lst->sled) : 0; }
static void pisi(Elem* lst) { // Ispisivanje liste.
if (lst)
Pii glavu + pii rep.
{ cout << lst->broj << ' '; pisi(lst->sled); }
}
static void naKraj(Elem*& lst, int b) {
// Dodavanje na kraj.
if (!lst) lst = new Elem(b);
Ako je lista prazna, napravi jedan element
else naKraj(lst->sled, b);
}
inae, dodaj na kraj repa.
static void citaj1(Elem*& lst, int n) {
// itanje stavljajui na
if (n) {
//
poetak.
lst = new Elem(0);
citaj1(lst->sled, n-1);
itaj rep + itaj glavu.
cin >> lst->broj;
}
}
static void citaj2(Elem*& lst, int n) {
// itanje stavljajui na kraj.
if (n) {
int b; cin >> b; lst = new Elem(b);
itaj glavu + itaj rep.
citaj2(lst->sled, n-1);
}
}
static void umetni(Elem*& lst, int b) {
// Umetanje u ureenu listu.
if (!lst || lst->broj>=b)
Ako je lista prazna ili je broj ispred
lst = new Elem(b, lst);
else
glave, stavi listu iza broja inae,
umetni(lst->sled, b);
umetni broj u rep.
}
static void brisi(Elem*& lst) {
// Oslobaanje memorije.
if (lst) { brisi(lst->sled);
Brii rep + brii glavu.
delete lst; lst = nullptr; }
}
static void izostavi(Elem*& lst, int b) { // Izostavljanje svakog
if (lst) { izostavi(lst->sled, b);
//
pojavljivanja.
if (lst->broj == b) {
Izostavi broj iz repa. Posle brii glaElem* stari = lst;
lst = lst->sled; delete stari;
vu ako je jednak broju.
}
}
}
};
// lista3t.C - Ispitivanje klase listi celih brojeva.

Napisati na jeziku C++ klasu ureenih binarnih stabala celih brojeva. Predvideti:
stvaranje praznog stabla, stabla od jednog broja i stabla kao kopiju drugog stabla,
unitavanje stabla,
ispitivanje da li je stablo prazno i odreivanje broja vorova u stablu,
izraunavanje zbira brojeva u vorovima stabla,
ispisivanje sadraja stabla na glavnom izlazu po prefiksnom (koren levo podstablo desno podstablo), infiksnom (levo podstablo koren desno podstablo) i postfiksnom (levo podstablo desno podstablo koren) redosledu,
grafiki prikaz sadraja stabla na glavnom izlazu,
odreivanje broja pojavljivanja date vrednosti u stablu,
odreivanje vrednosti najmanjeg i najveeg podatka u stablu,
pronalaenje vora u stablu koji sadri zadati broj,
dodavanje novog broja u stablo,
itanje stabla sa zadatim brojem vorova s glavnog ulaza,
pranjenje stabla,
izostavljanje datog broja iz stabla, i
balansiranje stabla.
Napisati na jeziku C++ interaktivni program za ispitivanje prethodne klase.
Reenje:
koren

stb:

levo
podstablo

list

5
7

desno
podstablo

6
8

null

null

5
null

null

null

null

null

6
null

null

Ureeno stablo:

Za bilo koji vor vai da su sve vrednosti u levom podstablu manje ili jednake, a u
desnom podstablu vee ili jednake od vrednosti u voru (neopadajui redosled).
Balansirano stablo: Za bilo koji vor vai da razlika broja vorova u levom i desnom podstablu nije
vea od jedan.
// stablo.h - Definicija klase ureenih binarnih stabala.
#include <iostream>
#include <iomanip>
#include <cstdlib>
using namespace std;
class Stablo {
struct Cvor {
// VOR STABLA:
int broj;
// - sadraj vora,
Cvor *levo, *desno;
// - levo i desno podstablo,
Cvor(int b, Cvor* l=nullptr, Cvor* d=nullptr) // - konstruktor.
{ broj = b; levo = l; desno = d; }
};
Cvor* stb;
// Pokaziva na koren stabla.

#include "lista3.h"
Nastavak se doslovce poklapa sa lista2t.C

Zadatak 2.9

Zadatak 2.10 Ureena stabla brojeva

2 Klase

2 Klase

Zadatak 2.10

58

59

public:
Stablo() {stb = nullptr; }
// Prazno stablo.
Stablo(int b) { stb = new Cvor(b); }
// Konverzija.
Stablo(const Stablo& s) { stb = kopiraj(s.stb); }
// Kopiranje.
Stablo(Stablo&& s) { stb = s.stb; s.stb = nullptr; } // Premetanje.
~Stablo() { brisi(stb); }
// Destruktor.
bool prazno() const { return stb == nullptr; } // Da li je stablo prazno?
int vel() const { return vel(stb); }
// Broj vorova u stablu.
int zbir() const { return zbir(stb); }
// Zbir brojeva u stablu.
void pisiKLD() const { pisiKLD(stb); }
// Prefiksno pisanje.
void pisiLKD() const { pisiLKD(stb); }
// Infiksno pisanje.
void pisiLDK() const { pisiLDK(stb); }
// Postfiksno pisanje.
void crtaj() const { crtaj(stb, 0); }
// Grafiki prikaz stabla.
int pojav(int b) const
// Broj pojavljivanja.
{ return pojav(stb, b); }
int min() const {
// Najmanji u stablu.
if (!stb) exit(1);
//
(ne sme biti prazno)
return min(stb);
}
int max() const {
// Najvei u stablu.
if (!stb) exit(1);
//
(ne sme biti prazno)
return max(stb);
}
Cvor* nadji(int b) const
// Traenje u stablu.
{ return nadji(stb, b); }
void dodaj(int b) { dodaj(stb, b); }
// Dodavanje u stablo.
void citaj(int n);
// itanje stabla.
void prazni() { brisi(stb); }
// Pranjenje stabla.
void izost(int b) { izost(stb, b); }
// Izostavljanje iz stabla.
void balans() { balans(stb); }
// Balansiranje stabla.
private:
// POMONE REKURZIVNE METODE:
static Cvor* kopiraj(Cvor* stb) {
// Kopiranje stabla.
return stb ?
new Cvor(stb->broj, kopiraj(stb->levo), kopiraj(stb->desno)) : 0;
}
static int vel(Cvor* stb)
// Broj vorova u stablu.
{ return stb ? 1 + vel(stb->levo) + vel(stb->desno) : 0; }
static int zbir(Cvor* stb)
// Zbir brojeva u stablu.
{ return stb ? stb->broj + zbir(stb->levo) + zbir(stb->desno) : 0; }
static void pisiKLD(Cvor* stb) {
// Prefiksno ispisivanje.
if (stb) {
cout << stb->broj << ' '; pisiKLD(stb->levo); pisiKLD(stb->desno);
}
}
static void pisiLKD(Cvor* stb) {
// Infiksno ispisivanje.
if (stb) {
pisiLKD(stb->levo); cout << stb->broj << ' '; pisiLKD(stb->desno);
}
}
static void pisiLDK(Cvor* stb) {
// Postfiksno ispisivanje.
if (stb) {
pisiLDK(stb->levo); pisiLDK(stb->desno); cout << stb->broj << ' ';
}
}

Zadatak 2.10

2 Klase

static void crtaj(Cvor* stb, int nivo) { // Grafiki prikaz stabla.


if (stb) {
3
crtaj(stb->desno, nivo+1);
cout << setw(4*nivo) << "" << stb->broj << endl;
crtaj(stb->levo, nivo+1);
6
}
1
}
5
static int pojav(Cvor* stb, int b) {
// Broj pojavljivanja
return stb ? (stb->broj==b)+pojav(stb->levo,b) // u stablu
+pojav(stb->desno,b)
: 0;
}

7
2
4

static int min(Cvor* stb)


// Najmanji u stablu.
{ return stb->levo ? min(stb->levo) : stb->broj; }
static int max(Cvor* stb)
// Najvei u stablu.
{ return stb->desno ? max(stb->desno) : stb->broj; }
static Cvor* nadji(Cvor* stb, int b){
// Traenje
if (!stb)
return nullptr;
if (stb->broj == b) return stb;
if (stb->broj > b) return nadji(stb->levo, b);
return nadji(stb->desno, b);
}

u stablu.

Ako broj nije u korenu,


dovoljno je pretraiti samo levo ili samo desno
podstablo.

static void dodaj(Cvor*& stb, int b) {


// Dodavanje u stablo.
if (!stb)
stb = new Cvor(b);
Ako je stablo prazno, novi vor
else if (stb->broj > b) dodaj(stb->levo, b);
postaje jedini u stablu. Inae,
else if (stb->broj < b) dodaj(stb->desno, b);
dodaje se u levo ili desno podelse if (rand()/(RAND_MAX+1.) < 0.5)
stablo, zavisno od odnosa predodaj(stb->levo, b);
ma sadraju korena. U sluaju
else
dodaj(stb->desno, b);
jednakosti, levo ili desno pod}

stablo se bira sluajno. Novi


vor bie list u stablu.

static void brisi(Cvor*& stb) {


// Oslobaanje memorije.
if (stb) {
brisi(stb->levo); brisi(stb->desno); delete stb; stb = nullptr;
}
}
static void izost(Cvor*& stb, int b) {
// Izostavljanje iz stabla.
if (stb) {
if
(stb->broj > b) izost(stb->levo, b);
else if (stb->broj < b) izost(stb->desno, b);
else if (stb->levo) {
Ako broj nije u listu, sadraj vora
int m = max(stb->levo);
mora da se zameni neim. U obzir dostb->broj = m; izost(stb->levo, m);
lazi najvei broj u levom podstablu ili
} else if (stb->desno) {
int m = min(stb->desno);
najmanji broj u desnom podstablu.
stb->broj = m; izost(stb->desno, m);
} else {
delete stb; stb = nullptr;
}
}
}
static void balans(Cvor*& stb);
};
2 Klase

// Balansiranje stabla.

Zadatak 2.10

60

61

// stablo.C - Deficije metoda klase ureenih binarnih stabala.


#include "stablo.h"
void Stablo::citaj(int n) {
// itanje stabla.
brisi(stb);
for (int i=0; i<n; i++) { int b; cin >> b; dodaj(b); }
}
void Stablo::balans(Cvor*& stb) {
// Balansiranje stabla.
if (stb) {
int k = vel(stb->levo) - vel(stb->desno);
for (; k>1; k-=2) {
dodaj(stb->desno, stb->broj);
Sve dok je levo podstablo preveliko,
stb->broj = max(stb->levo );
sadraj korena se ubacuje u desno podizost(stb->levo , stb->broj);
stablo, a najvei broj iz levog podstabla
}
for (; k<-1; k+=2) {
premeta se u koren. Slino se postupa
dodaj(stb->levo , stb->broj);
i ako je desno podstablo preveliko. Na
stb->broj = min(stb->desno);
kraju, potrebno je odvojeno balansirati
izost(stb->desno, stb->broj);
levo i desno podstablo.
}
balans(stb->levo );
balans(stb->desno);
}
}
// stablot.C - Ispitivanje klase ureenih binarnih stabala.
#include "stablo.h"
#include <iostream>
using namespace std;
// Primena operacije na stablo za svaki proitani broj:
void radi(Stablo& stb, void (Stablo::*pf)(int)) {
int b; cout << "Brojevi?
";
do { cin >> b; (stb.*pf)(b); } while (cin.get() != '\n');
}
// do kraja reda
int main() {
Stablo stb; bool kraj = false;
while (!kraj) {
cout << endl <<
"a) Dodavanje brojeva
"b) Izostavljanje brojeva
"c) Citanje stabla
"d) Najmanji element
"e) Najveci element
"f) Pretrazivanje
"g) Balansiranje
"h) Praznjenje stabla
"
"Vas izbor? ";
char izbor; cin >> izbor;

Zadatak 2.10

Pisanje stabla:\n"
1. koren-levo-desno\n"
2. levo-koren-desno (uredjeno)\n"
3. levo-desno-koren\n"
4. crtanje\n"
i) Velicina stabla\n"
j) Zbir elemenata\n"
k) Broj pojavljivanja\n"
z) Zavrsetak rada\n\n"

2 Klase

switch (izbor) {
int broj;
case 'a': case 'A':
// Dodavanje brojeva u stablo:
radi(stb, &Stablo::dodaj); break;
case 'b': case 'B':
// Izostavljanje brojeva iz stabla:
radi(stb, &Stablo::izost); break;
case 'c': case 'C':
// itanje stabla:
cout << "Duzina?
"; int n; cin >> n;
cout << "Brojevi?
"; stb.citaj(n);
break;
case 'd': case 'D': case 'e': case 'E':
if (!stb.prazno()) switch (izbor) {
case 'd': case 'D': // Najmanji element stabla:
cout << "min=
" << stb.min(); break;
case 'e': case 'E': // Najvei element stabla:
cout << "max=
" << stb.max(); break;
} else cout << "*** Stablo je parzno! ***\a\n";
break;
case 'f': case 'F':
// Pretraivanje stabla:
cout << "Broj?
"; cin >> broj;
cout << "Broj se" << (stb.nadji(broj) ? "" : " NE")
<< " nalazi u stablu.\n";
break;
case 'g': case 'G':
// Balansiranje stabla:
stb.balans(); break;
case 'h': case 'H':
// Pranjenje stabla:
stb.prazni(); break;
case 'i': case 'I':
// Veliina stabla:
cout << "Vel=
" << stb.vel() << endl; break;
case 'j': case 'J':
// Zbir elemenata stabla:
cout << "Zbir=
" << stb.zbir() << endl; break;
case 'k': case 'K':
// Broj pojavljivanja datog broja:
cout << "Broj?
"; cin >> broj;
cout << "Broj se pojavljuje " << stb.pojav(broj) << " puta.\n";
break;
case '1':
// Pisanje stabla koren-levo-desno:
cout << "Stablo=
"; stb.pisiKLD(); cout << endl; break;
case '2':
// Pisanje stabla levo-koren-desno:
cout << "Stablo=
"; stb.pisiLKD(); cout << endl; break;
case '3':
// Pisanje stabla levo-desno-koren:
cout << "Stablo=
"; stb.pisiLDK(); cout << endl; break;
case '4':
// Crtanje stabla:
stb.crtaj(); break;
case 'z': case 'Z':
// Zavretak rada:
kraj = true; break;
default:
// Pogrean izbor:
cout << "*** Nedozvoljen izbor! ***\a\n"; break;
}

2 Klase

Zadatak 2.10

62

63

% stablot
a)
b)
c)
d)
e)
f)
g)
h)

Zadatak 2.11 Nizovi materijalnih taaka

Dodavanje brojeva
Izostavljanje brojeva
Citanje stabla
Najmanji element
Najveci element
Pretrazivanje
Balansiranje
Praznjenje stabla

Vas izbor? a
Brojevi?
5 7 4 3

Vas izbor? 4
9
8
7
6
5
5
4
3
2
1

Vas izbor? 1
Stablo=
5 4 3 2

Vas izbor? 2
Stablo=
1 2 3 4

Vas izbor? 3
Stablo=
1 2 3 5

Vas izbor? g

Vas izbor? 4
9
8
7
6
5
5
4
3
2
1

Vas izbor? 1
Stablo=
5 3 2 1

Vas izbor? 2
Stablo=
1 2 3 4

Vas izbor? 3
Stablo=
1 2 4 5

Vas izbor? z

Zadatak 2.10

Pisanje stabla:
1. koren-levo-desno
2. levo-koren-desno (uredjeno)
3. levo-desno-koren
4. crtanje
i) Velicina stabla
j) Zbir elemenata
k) Broj pojavljivanja
z) Zavrsetak rada

Napisati na jeziku C++ sledee klase (klase opremiti onim konstruktorima i destruktorom koji su potrebni za bezbedno korienje klasa):
Materijalna taka u prostoru zadaje se pomou realne mase (podrazumevano 1) i tri realne koordinate (podrazumevano (0,0,0)). Moe da se odredi rastojanje (r) do druge take, da se izrauna privlana sila izmeu take i zadate druge take (F=m1m2/r2, =6,671011) i da se taka ispie na
glavnom izlazu.
Niz materijalnih taaka stvara se prazan, zadatog poetnog kapaciteta (podrazumevano 5), posle
ega se take dodaju pojedinano na kraj niza. Ako se niz prepuni, kapacitet mu se povea za 5.
Moe da se dohvati broj taaka u nizu, da se dohvati taka u nizu koja najvie privlai zadatu taku
i da se niz ispie na glavnom izlazu.
Napisati na jeziku C++ program koji itajui materijalne take s glavnog ulaza napravi niz materijalnih
taaka (itanje se zavrava unosom negativne mase), ispie na glavnom izlazu dobijeni niz kao i taku
koja najvie privlai taku jedinine mase u koordinatnom poetku i ponavlja prethodne korake sve dok
ne proita prazan niz (niz duine 0).

9 8 2 6 5 1
9
7
5
4

6
5
3

Reenje:
2

// mattacka.h - Definicija klase materijalnih taaka.

#include <iostream>
#include <cmath>
using namespace std;

1 5 7 6 9 8

class Mat_tacka {
double m, x, y, z;
// Masa i koordinate take.
public:
explicit Mat_tacka(double mm=1, double xx=0, // Stvaranje take.
double yy=0, double zz=0)
{ m = mm; x = xx; y = yy; z = zz; }
double r(const Mat_tacka& mt) const
// Rastojanje do take.
{ return sqrt(pow(x-mt.x,2) + pow(y-mt.y,2) + pow(z-mt.z,2)); }
double F(const Mat_tacka& mt) const
// Privlana sila.
{ return 6.67e-11 * m * mt.m / pow(r(mt),2); }
void pisi() const
// Pisanje take.
{ cout << '[' << m << ",(" << x << ',' << y << ',' << z <<")]"; }
};

5 5 6 7 8 9
4 6 8 9 7 5

9
7
5

6
5

// nizmatac.h - Definicija klase nizova materijalnih taaka.

#include "mattacka.h"
class Niz_mat_tac {
Mat_tacka* niz;
int kap, duz;
public:
explicit Niz_mat_tac(int k=5) {
niz = new Mat_tacka [kap = k];
duz = 0;
}
Niz_mat_tac(const Niz_mat_tac& nmt);
Niz_mat_tac(Niz_mat_tac&& nmt) {
niz = nmt.niz; nmt.niz = nullptr;
kap = nmt.kap; duz = nmt.duz;
}

5 4 7 6 9 8
5 5 6 7 8 9
3 6 8 9 7 5

2 Klase

2 Klase

// Niz taaka.
// Kapacitet i duina niza.
// Stvaranje praznog niza.

// Kopirajui konstruktor.
// Premetajuikonstruktor.

Zadatak 2.11

64

65

~Niz_mat_tac() { delete [] niz; }


int vel() const { return duz; }
Niz_mat_tac& dodaj(const Mat_tacka& mt);
Mat_tacka max_F(const Mat_tacka& mt) const;
void pisi() const;
};

//
//
//
//
//

Destruktor.
Veliina niza.
Dodavanje take.
Najjaa taka.
Pisanje niza.

// nizmtact.C - Ispitivanje klase nizova materijalnih taaka.


#include "nizmtac.h"
#include <iostream>
using namespace std;

// nizmtac.C - Definicije metoda klase nizova materijalnih taaka.


#include "nizmtac.h"
#include <iostream>
using namespace std;
Niz_mat_tac::Niz_mat_tac(const Niz_mat_tac& nmt) {// Kopirajui konstruktor.
niz = new Mat_tacka [kap = nmt.kap];
duz = nmt.duz;
for (int i=0; i<duz; i++) niz[i] = nmt.niz[i];
}
Niz_mat_tac& Niz_mat_tac::dodaj(const Mat_tacka& mt) { // Dodavanje take.
if (duz == kap) {
Mat_tacka* pom = new Mat_tacka [kap += 5];
for (int i=0; i<duz; i++) pom[i] = niz[i];
delete [] niz; niz = pom;
}
niz[duz++] = mt;
return *this;
}
Mat_tacka Niz_mat_tac::max_F(const Mat_tacka& mt) const { // Najjaa taka.
double max = mt.F(niz[0]);
int ind = 0;
for (int i=1; i<duz; i++) {
double F = mt.F(niz[i]);
if (F > max) { max = F; ind = i; }
}
return niz[ind];
}

int main() {
while (true) {
Niz_mat_tac niz;
while (true) {
cout << "m,x,y,z? "; double m, x, y, z; cin >> m >> x >> y >> z;
if (m < 0) break;
niz.dodaj(Mat_tacka(m,x,y,z));
}
if (niz.vel() == 0) break;
cout << "Niz tacaka:\n"; niz.pisi();
cout << "Najvise privlaci: ";
niz.max_F(Mat_tacka()).pisi(); cout << endl;
}
}
% nizmtact
m,x,y,z? 5 3 4 5
m,x,y,z? 1 1 1 1
m,x,y,z? 8 2 9 4
m,x,y,z? -1 0 0 0
Niz tacaka:
[5,(3,4,5)]
[1,(1,1,1)]
[8,(2,9,4)]
Najvise privlaci: [1,(1,1,1)]
m,x,y,z? -1 0 0 0

void Niz_mat_tac::pisi() const {


// Pisanje niza.
for (int i=0; i<duz; i++) { niz[i].pisi(); cout << endl; }
}

+
+
+
+

Zadatak 2.11

Mat_tacka
m, x, y, z
Mat_tacka() -niz
r()
*
F()
pisi()

+
+
+
+
+
+

Niz_m_tac
kap, duz
Niz_m_Tac()
~Niz_m_tac()
vel()
dodaj()
max_F()
pisi()

2 Klase

2 Klase

Zadatak 2.11

66

67

// datum2.C - Definicija statikog polja uz klasu datuma.

Zadatak 2.12 Liste datuma


Napisati na jeziku C++ sledee klase (klase opremiti onim konstruktorima i destruktorom koji su potrebni za bezbedno korienje klasa):
Datum se zadaje pomou broja dana, meseca i godine. Moe da se proveri da li tri cela broja predstavljaju ispravan datum, da se stvara datum na osnovu tri cela broja (podrazumevano 1.7.2011.
pogrean datum prekida program), da se dohvataju delovi datuma, da se datum uporedi s drugim
datumom (rezultat je <0, =0 ili >0, zavisno od toga da li je tekui datum pre, jednak ili posle zadatog datuma), da se datum proita s glavnog ulaza (povratna vrednost je indikator uspeha) i da se
datum ispie na glavnom izlazu.
Lista datuma se stvara prazna, posle ega se datumi dodaju pojedinano na kraj liste. Moe da se
odredi duina liste, da se dohvati pokaziva na najkasniji datum u listi i da se lista ispie na glavnom izlazu.
Napisati na jeziku C++ program koji itajui datume s glavnog ulaza napravi listu datuma (itanje se zavrava
prvim neispravnim datumom), ispie na glavnom izlazu dobijenu listu kao i najkasniji datum i ponavlja
prethodne korake sve dok ne proita praznu listu.
Reenje:
// datum2.h - Definicija klase kalendarskih datuma.
#include <iostream>
#include <cstdlib>
using namespace std;
class Datum {
int d, m, g;
// Dan, mesec i godina.
static int dani[2][12];
// Brojevi dana po mesecima.
public:
static bool moze(int d, int m, int g)
// Da li je ispravan?
{ return g>0 && m>0 && m<=12 && d>0 && d<=dani[g%4==0][m-1]; }
explicit Datum(int dd=1, int mm=7, int gg=2011) { // Stvaranje datuma.
if (!moze(dd, mm, gg)) exit(1);
d = dd; m = mm; g = gg;
}
int dan() const { return d; }
// Dohvatanje delova datuma.
int mes() const { return m; }
int god() const { return g; }
int uporedi(const Datum& dat) const {
// Uporeivanje datuma.
if (g != dat.g) return g - dat.g;
if (m != dat.m) return m - dat.m;
return d - dat.d;
}
bool citaj() {
// itanje datuma.
int d, m, g; cin >> d >> m >> g;
if (!moze(d, m, g)) return false;
*this = Datum(d, m, g); return true;
}
void pisi() const
// Pisanje datuma.
{ cout << d << '.' << m << '.' << g << '.'; }
};

Zadatak 2.12

2 Klase

#include "datum2.h"
int Datum::dani[2][12] = {
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
// listadat.h - Definicija klase listi datuma.
#include "datum2.h"
class Lista {
struct Elem {
Datum dat;
Elem* sled;
Elem(const Datum& d)
{ dat = d; sled = nullptr; }
};

//
//
//
//

ELEMENT LISTE:
- sadrani datum,
- pokaziva na sledei element,
- konstruktor.

Elem *prvi, *posl;


// Pokaziva na poetak i kraj liste.
int duz;
// Duina liste.
public:
// Konstruktori:
Lista() { prvi = posl = nullptr; duz = 0; } // - podrazumevani,
Lista(const Lista& lst);
// - kopirajui,
Lista(Lista&& lst) {
// - premetajui.
prvi = lst.prvi; posl = lst.posl;
duz = lst.duz; lst.prvi = lst.posl = nullptr; }
~Lista();
// Destruktor.
Lista& dodaj(const Datum& dat) {
// Dodavanje datuma.
posl = (!prvi ? prvi : posl->sled) = new Elem(dat);
duz++;
return *this;
}
int duzina() const { return duz; }
// Duina liste.
const Datum* max() const;
// Najkasniji (sveiji) datum.
void pisi() const;
// Pisanje liste.
};
// listadat.C - Definicije metoda klase listi datuma.
#include "listadat.h"
#include <iostream>
using namespace std;
Lista::Lista(const Lista& lst) {
// Kopirajui konstruktor.
prvi = posl = nullptr; duz = 0;
for (Elem* tek=lst.prvi; tek; tek=tek->sled) dodaj(tek->dat);
}
Lista::~Lista() {
// Destruktor.
while (prvi) { Elem* stari = prvi; prvi = prvi->sled; delete stari; }
}

2 Klase

Zadatak 2.12

68

69

const Datum* Lista::max() const {


// Najkasniji (sveiji) datum.
if (!prvi) return nullptr;
Datum* m = &prvi->dat;
for (Elem* tek=prvi->sled; tek; tek=tek->sled)
if (m->uporedi(tek->dat) < 0) m = &tek->dat;
return m;
}
void Lista::pisi() const {
// Pisanje liste.
for (Elem* tek=prvi; tek; tek=tek->sled)
{ tek->dat.pisi(); cout << ' '; }
}

+
+
+
+
+
+
+
+

Datum
d, g, m
dani[][]
moze()
+datum
Datum()
dan()
1
mes()
god()
uporedi()
citaj()
pisi()

-prvi
0..1

Lista::Elem
+ Elem()
-sled

-posl
0..1

0..1

+
+
+
+
+
+

Zadatak 2.13 JMBG, osobe i imenici


Napisati na jeziku C++ sledee klase (klase opremiti onim konstruktorima i destruktorom koji su potrebni za bezbedno korienje klasa):
Jedinstveni matini broj graana (JMBG) sadri nisku fiksne duine od 13 cifara, koja se zadaje
pri stvaranju i moe da se dohvati. Moe da se ispita da li je zadati JMBG vei od drugog zadatog
JMBG i da se JMBG ispie na glavnom izlazu raunara.
Osoba ima ime i JMBG koji se zadaju pri stvaranju i mogu da se dohvate. Ime je niska proizvoljne
duine. Osoba moe da se ispie na glavnom izlazu raunara u obliku ime(jmbg).
Imenik moe da sadri proizvoljan broj osoba po rastuem redosledu njihovih JMBG. Stvara se
prazan posle ega se osobe dodaju pojedinano. Sadraj imenika moe da se ispie na glavnom
izlazu raunara, jedna osoba po redu.
Napisati na jeziku C++ program koji napravi imenik s nekoliko osoba i ispie ga na glavnom izlazu raunara. Koristiti fiksne parametre nije potrebno nita uitavati s glavnog ulaza.

Lista
duz
Lista()
~Lista()
dodaj()
duzina()
max()
pisi()

Reenje:
// jmbg.h Definicija klase jedinstvenih matinih brojeva graana.
#include <cstring>
#include <iostream>
using namespace std;

// listadatt.C - Ispitivanje klase listi datuma.


#include "listadat.h"
#include <iostream>
using namespace std;

class JMBG {
char jmbg[14];
// Jedinstveni matini broj.
public:
JMBG(const char j[]) { strcpy(jmbg, j); }
// Konstruktor.
const char* dohv_JMBG() const { return jmbg; }
// Dohvatanje broja.
friend bool veci(const JMBG& j1, const JMBG& j2) // Uporeivanje.
{ return strcmp(j1.jmbg, j2.jmbg) > 0; }
void pisi() const { cout << jmbg; }
// Pisanje.
};

int main() {
while (true) {
Lista lst;
while (true) {
cout << "Datum (d,m,g)? "; int d, m, g; cin >> d >> m >> g;
if (!Datum::moze(d, m, g)) break;
lst.dodaj(Datum(d, m, g));
}
if (lst.duzina() == 0) break;
cout << "Lista= "; lst.pisi(); cout << endl;
cout << "Najkasnije= "; lst.max()->pisi(); cout << endl;
}
}

// osoba1.h - Definicija klase osoba.


#include "jmbg.h"
#include <string>
#include <iostream>
using namespace std;
class Osoba {
string ime;
// Ime osobe.
JMBG jmbg;
// Jedinstveni matini broj.
public:
Osoba(string i, JMBG j): jmbg(j), ime(i) {} // Stvaranje.
string dohv_ime() const { return ime; }
// Dohvatanje imena.
JMBG dohv_JMGB() const { return jmbg; }
// Dohvatanje JBMG.
void pisi() const
// Pisanje.
{ cout << ime << '('; jmbg.pisi(); cout << ')'; }
};

% listadatt
Datum (d,m,g)? 2 9 2014
Datum (d,m,g)? 12 5 1986
Datum (d,m,g)? 31 8 2011
Datum (d,m,g)? 3 12 1999
Datum (d,m,g)? 31 2 2001
Lista= 2.9.2014. 12.5.1986. 31.8.2011. 3.12.1999.
Najkasnije= 2.9.2014.
Datum (d,m,g)? 0 0 0

Zadatak 2.12

2 Klase

2 Klase

Zadatak 2.13

70

71

// imenik1.h - Definicija klase imenika.

// imenik1t.C - Ispitivanje klase imenika.

#include "osoba1.h"

#include "imenik1.h"
#include <iostream>
using namespace std;

class Imenik {
struct Elem {
//
Osoba oso;
//
Elem* sled;
//
Elem(const Osoba& o, Elem* s=nullptr) //
: oso(o) { sled = s; }
};
Elem* prvi;
//
public:
Imenik() { prvi = nullptr; }
//
Imenik(const Imenik& im);
//
Imenik(Imenik&& im)
//
{ prvi = im.prvi; im.prvi = nullptr; }
~Imenik();
//
Imenik& dodaj(const Osoba& oso);
//
void pisi() const;
//
};

Element liste:
- sadrana osoba,
- pokaziva na sledei element,
- konstruktor.
Pokaziva na poetak liste.
Stvaranje praznog imenika.
Kopirajui konstruktor.
Premetajui konstrukotr.

int main() {
Imenik im;
im.dodaj(Osoba("Marko",
.dodaj(Osoba("Milan",
.dodaj(Osoba("Zoran",
.dodaj(Osoba("Petar",
.dodaj(Osoba("Stevo",
.pisi();
}

JMBG("1205986110022")))
JMBG("3112969235052")))
JMBG("1511990872035")))
JMBG("0207000345678")))
JMBG("2503973123024")))

% imenik1t
Petar(0207000345678)
Marko(1205986110022)
Zoran(1511990872035)
Stevo(2503973123024)
Milan(3112969235052)

Destruktor.
Dodavanje osobe.
Pisanje imenika.

// imenik1.C - Definicije metoda klase imenika.


#include "imenik1.h"
#include <iostream>
using namespace std;
Imenik::Imenik(const Imenik& im) {
// Kopirajui konstruktor.
prvi = nullptr;
for (Elem *tek=im.prvi, *posl=nullptr; tek; tek=tek->sled)
posl = (!prvi ? prvi : posl->sled) = new Elem(tek->oso);
}
Imenik::~Imenik() {
// Destruktor.
while (prvi) { Elem* stari = prvi; prvi = prvi->sled; delete stari; }
}
Imenik& Imenik::dodaj(const Osoba& oso) { // Dodavanje osobe.
Elem *tek=prvi, *pret=nullptr;
while (tek && veci(oso.dohv_JMGB(), tek->oso.dohv_JMGB()))
{ pret = tek; tek = tek->sled; }
(!pret ? prvi : pret->sled) = new Elem(oso, tek);
return *this;
}
void Imenik::pisi() const {
// Pisanje imenika.
for (Elem* tek=prvi; tek; tek=tek->sled)
{ tek->oso.pisi(); cout<<endl; }
}

+
+
+
+

JMBG
jmbg[]
-jmbg
JMBG()
dohv_JMBG()
1
veci()
pisi()

Zadatak 2.13

+
+
+
+
+

Osoba
ime
+oso
Osoba()
~Osoba()
dohv_ime() 1
dohv_JMBG()
pisi()

Imenik::Elem
+ Elem()
+sled

-prvi
0..1

+
+
+
+

Imenik
Imenik()
~Imenik()
dodaj()
pisi()

0..1

2 Klase

2 Klase

Zadatak 2.13

You might also like