You are on page 1of 29

Funkcije. Varijabilni parametri.

Polja kao
parametri
Auditorne vježbe
Primjer 1 – Razmjena pisama

 ULAZ: Prirodni broj N i polje P[N] koje sadrži brojeve od 0..N-1 (koji nisu
sortirani)
 IZLAZ: Poštar je ispostavio N pisama na krive adrese. Treba napraviti program
koji će rasporediti pisma po naznačenim adresama u što je manje moguće
koraka. U svakom koraku svaka osoba koji ima pismo koje nije njegovo
razmjenjuje pismo s nekom drugom osobom.

Prof. dr. sc. Alen Lovrenčić Page 2


Primjer 1 – Razmjena pisama

 U svakom koraku polovica od svih osoba krene vratiti pismo pravom


vlasniku i od njih uzima pismo koje oni imaju.
 U drugom koraku polovica od preostalih osoba koji nemaju svoje pismo
čini to isto i tako se to ponavlja dok svatko ne dobije svoje pismo.

Prof. dr. sc. Alen Lovrenčić Page 3


Primjer 1 – Razmjena pisama

 Dakle, u svakom koraku će najmanje polovica ljudi dobiti svoje pismo, pa će


nakon log2N svi imati svoje pismo
 Ovo je zasigurno optimalno, jer je jedina mogućnost da više od polovice osoba u
nekom koraku dobije svoje pismo ona kada obje osobe zamjenom dobiju svoja
pisma. Samo trebamo paziti da sve osobe (osim možda jedne kada je neparni
broj osoba) sudjeluju u razmjeni.

Prof. dr. sc. Alen Lovrenčić Page 4


Primjer 1 – Razmjena pisama

 Organizacija podataka
 Ulazni podaci dani su u polju duljine N koje sadrži različite brojeve
između 0..N-1.
 Broj u i-tom elementu ulaznog polja predstavlja broj osobe kome pripada
pismo koje i-ta osoba trenutno posjeduje.

Prof. dr. sc. Alen Lovrenčić Page 5


Primjer 1 – Razmjena pisama

 Funkcija Init inicijalizirat će varijablu M, koja će sadržavati broj pogrešno


podijeljenih pisama
 Postoji mogućnost da je već u početnoj podjeli pisama neki čovjek dobio svoje
pismo, pa njega treba isključiti iz razmjena.

Prof. dr. sc. Alen Lovrenčić Page 6


Primjer 1 – Razmjena pisama

1. Za i = 0..N-1 radi
2. M=N
3. Ako je A[i] = i
4. M=M-1
5. vrati M

Prof. dr. sc. Alen Lovrenčić Page 7


Primjer 1 – Razmjena pisama

#include <iostream>
using namespace std;

1. Za i = 0..N-1 radi
2. M=N
3. Ako je A[i] = i
4. M=M-1
5. vrati M

Prof. dr. sc. Alen Lovrenčić Page 8


Primjer 1 – Razmjena pisama

#include <iostream>
using namespace std;

int Init (int A[], int N) {


int M = N;
for (int i = 0; i<N; i++)
if (A[i] == i)
M--;
return M;
}

Prof. dr. sc. Alen Lovrenčić Page 9


Primjer 1 – Razmjena pisama

 Sljedeća funkcija koju ćemo napraviti jest funkcija koja će ispisivati


trenutni raspored pisama.

Prof. dr. sc. Alen Lovrenčić Page 10


Primjer 1 – Razmjena pisama

1. Za i = 0..N
2. Ispiši A[i]

Prof. dr. sc. Alen Lovrenčić Page 11


Primjer 1 – Razmjena pisama

void Ispis (int *A, int N) {


for (int i = 0; i < N; i++)
cout << A[i] << "\t";
cout << endl << endl;
}

Prof. dr. sc. Alen Lovrenčić Page 12


Primjer 1 – Razmjena pisama

 Konačno smo došli do funkcije za razmjenu.


 U njoj nalazimo prvih M/2 osoba koje još nemaju svoje pismo i oni razmjenjuju
pismo s osobom kojoj to pismo pripada. Ta osoba dobija svoje pismo.
 Ono što se može dogoditi jest da nekom razmjenom obije osobe dobiju svoj
pismo. To treba imati na umu.
 Kao parametre ove funkcije dat ćemo polje te varijablu M koja će sadržavati broj
osoba koje još nemaju svoje pismo.
 U funkciji ćemo imati petlju od 0..M/2-1 razmjena
 U svakom koraku petlje traži se prvi element polja za koji vrijedi A[k] != k i on se
mijenja s A[k]-tim elementom, a broj M se smanjuje za 1 ili 2 ovisno o tome je li u
razmjeni samo jedna ili obije osobe dobile svoje pismo.
 Morat ćemo koristiti dodatnu varijablu MM, kako bismo osigurali da M ostaje isti
do kraja izvršavanja petlje
 Kako je M i parametar i rezultat, napravit ćemo funkciju tipa void, koja će kao
parametar prihvaćati pokazivač na M, tako da omogućimo promjenu vrijednosti
varijable M koja će biti vidljiva i nakon završetka funkcije.

Prof. dr. sc. Alen Lovrenčić Page 13


Primjer 1 – Razmjena pisama

1. MM = M
2. Za i = 0..M/2-1 radi
3. Sve dok je (A[k] = k) radi k = k + 1
4. pom = A[k]
5. A[k] = A[A[k]]
6. Ako je A[k] = k onda MM = MM – 1
7. A[pom] = pom
8. MM = MM – 1
9. k=k+1
10. M = MM

Prof. dr. sc. Alen Lovrenčić Page 14


Primjer 1 – Razmjena pisama

void Razmjena (int *A, int N, int *M) {


int k = 0, MM = *M;
for (int i = 0; i < (*M)/2; i++) {
while (A[k] == k) k++;
Polje se kao parametar
int pom = A[k];
funkcije može deklarirati
A[k] = A[A[k]]; i ovako.
if (A[k] == k) MM--;
*A je jednako kao i A[]
A[pom] = pom;
MM--;
k++;
}
*M = MM;
}

Prof. dr. sc. Alen Lovrenčić Page 15


Primjer 1 – Razmjena pisama

 Na početku bismo trebali na neki način inicirati polje.


 Mogli bismo unositi brojeve između 0 i N-1 u polje ali tako da svi brojevi
budu različiti.
 No, za to bismo trebali napraviti dosta kontrola.
 Bolje će biti da početnu raspodjelu pisama napravimo "miješanjem"
 Miješanje će imati k koraka (uzet ćemo da je k = 1000)
 U svakom koraku miješanja zamijenit ćemo vrijednosti dvaju slučajno
odabranih elemenata polja.

Prof. dr. sc. Alen Lovrenčić Page 16


Primjer 1 – Razmjena pisama

1. Za i=0..k
2. i = RND(0..N-1)
3. j = RND(0..N-1)
4. pom = A[i]
5. A[i] = A[j]
6. A[j] = pom

Prof. dr. sc. Alen Lovrenčić Page 17


Primjer 1 – Razmjena pisama

void Mijesanje(int A[], int N, int k) {


for (int m = 0; m < k; m++) {
int i = rand()%N, j = rand()%N;
int pom = A[i];
A[i] = A[j];
A[j] = pom;
}
}

Prof. dr. sc. Alen Lovrenčić Page 18


Primjer 1 – Razmjena pisama

 Na kraju, glavni će program biti jednostavan i sastojat će se od unosa


parametara i poziva funkcija.

Prof. dr. sc. Alen Lovrenčić Page 19


Primjer 1 – Razmjena pisama

1. Radi
2. Učitaj N
3. sve dok je N<1
4. Alociraj polje A duljine N
5. Za I = 0..N-1 radi
6. A[i] = i
7. Mijesanje(A,N, 1000)
8. M = Init(A,N)
9. Ispis(A,N)
10. Sve dok je M>0 radi
11. Razmjena(A,N,&M)
12. Ispis(A,N)

Prof. dr. sc. Alen Lovrenčić Page 20


Primjer 1 – Razmjena pisama

int main () {
srand(time(0));
int N;
do {
cout << "N = ";
cin >> N;
} while (N<1);
int *A = new int [N];
for (int i = 0; i < N; i++) A[i] = i;
Mijesanje(A, N, 1000);
int M = Init(A, N);
Ispis(A,N);
while (M>0) {
Razmjena(A,N,&M);
Ispis(A,N);
}
system("pause");
return 0;
}

Prof. dr. sc. Alen Lovrenčić Page 21


Primjer 2 – Binomni koeficijent

 ULAZ: Prirodni brojevi N i K


 IZLAZ: Izračunati binomni koeficijent

N  N!
  
 K  K!(N  K )!

Prof. dr. sc. Alen Lovrenčić Page 22


Primjer 2 – Binomni koeficijent

 Formula na prethodnom slajdu daje ujedno i način kako se binomni koeficjient


može izračunati
 No, postoji znatno efikasniji način za izračunavanje binomnog koeficijenta
definiran Pascalovim trokutom:
K 0 1 2 3 4 5
n
0 1  N   N  1  N  1
       
1 1 1  K   K   K  1
2 1 2 1
3 1 3 3 1
4 1 4 6 4 1
5 1 5 10 10 5 1

Prof. dr. sc. Alen Lovrenčić Page 23


Primjer 2 – Binomni koeficijent

 Induktivna definicija rekurzije


 Baza: 0
   1
0
N 
   1
0
N 
   1
N 

 Pretpostavka: Pretpostavimo da znamo računati sve binomne koeficijente za


N-1
 Korak: Tada je
 N   N  1  N  1
       
 K   K   K  1

Prof. dr. sc. Alen Lovrenčić Page 24


Primjer 2 – Binomni koeficijent

 Pogledajmo rubne uvjete za rekuziju


 Jasno je da je rubni uvjet kada je N = 0
 No, rekurzija će se moći završiti i u još nekim slučajevima
- Ako je K = 0 onda se ne treba ići u rekurziju već se zaključuje da je rješenje 1
- Ako je N = K onda se ne treba ići u rekurziju već se zaključuje da je rješenje 1
 Pitanje je je li ova rekurzija uvijek završava.
 Pa na to je pitanje lako odgovoriti. Naime, svaki se koeficijent računa
kao dva koeficijenta kojima je N smanjen za 1. Dakle, u N razina
rekurzivnog poziva sigurno će se doći do N = 0 i stati.

Prof. dr. sc. Alen Lovrenčić Page 25


Primjer 2 – Binomni koeficijent

1. BinCoef(N,K)
2. Ako je N=0 ili K=0 ili K=N vrati 1
3. inače vrati BinCoef(N-1,K)+BinCoef(N-1,K-1)

Prof. dr. sc. Alen Lovrenčić Page 26


Primjer 2 – Binomni koeficijent

#include <iostream>
using namespace std;

int BinCoef (int N, int K) {


if (N==0 || K==0 || K == N) return 1;
else return BinCoef(N-1,K) + BinCoef(N-1,K-1);
}

Prof. dr. sc. Alen Lovrenčić Page 27


Primjer 2 – Binomni koeficijent

int main () {
int N,K;
do {
cout << "N = ";
cin >> N;
cout << "K = ";
cin >> K;
} while (N<K ||N<0 || K<0);
cout << N << endl;
cout << "\t = " << BinCoef(N,K) << endl;
cout << K << endl;
system("pause");
return 0;
}

Prof. dr. sc. Alen Lovrenčić Page 28


Zadatak

 Izračunati izraz (a+b)N preko formule

N  N  N   N  N 1  N  N
(a  b)N   aN   aN 1b   aN 2b2     ab   b
0 1 2  N  1 N 
 Pri izračunu je zabranjeno koristiti biblioteku cmath.

Prof. dr. sc. Alen Lovrenčić Page 29

You might also like