osnove algoritama oa-skripta

108
Sveuˇ ciliˇ ste u Zagrebu Prirodoslovno-matematiˇ cki fakultet Matematiˇ cki odsjek OSNOVE ALGORITAMA Predavanja Vedran Krˇ cadinac Akademska godina 2013./2014.

Upload: lisa-zimmerman

Post on 19-Oct-2015

116 views

Category:

Documents


9 download

DESCRIPTION

algoritmi

TRANSCRIPT

  • Sveuciliste u Zagrebu

    Prirodoslovno-matematicki fakultet

    Matematicki odsjek

    OSNOVE ALGORITAMA

    Predavanja

    Vedran Krcadinac

    Akademska godina 2013./2014.

  • Sadrzaj

    1 Pojam algoritma 1

    2 Brojevni sustavi 7

    3 Nacini zapisivanja algoritama 19

    4 Pseudojezik 27

    5 Neki algoritmi za prirodne brojeve 39

    6 Nizovi i sortiranje 53

    7 Jos neki matematicki algoritmi 67

    8 Prikaz brojeva u racunalu 83

    9 Rjesenja nekih zadataka 89

    Bibliografija 103

  • Poglavlje 1

    Pojam algoritma

    Pojam algoritma pokusat cemo objasniti kroz jednostavan primjer. Treba zbrojiti dvavelika prirodna broja bez kalkulatora, recimo 6247345 i 98492. Sjetimo se postupka zazbrajanje naucenog u osnovnoj skoli:

    1 1

    6 2 4 7 3 4 5+ 9 8 4 9 2

    6 3 4 5 8 3 7

    Ovdje nas ne zanima rezultat, nego postupak kojim do njega dolazimo to je prvi primjeralgoritma kojeg cemo obraditi!

    Pokusajmo precizno zapisati algoritam za zbrajanje. Kao prvo, na ovaj nacin mozemozbrojiti bilo koja dva prirodna broja. Na pocetku ih moramo zadati. Ulazni podaci algo-ritma za zbrajanje su dva prirodna broja zadana s pomocu svojih znamenaka:(am, am1, . . . , a2, a1) i (bn, bn1, . . . , b2, b1), gdje su ai, bj {0, 1, . . . , 9}. Brojevi nemoraju imati jednako mnogo znamenaka, tj. moze biti m 6= n. Medutim, mozemonadopisati vodece nule onom broju koji ima manje znamenaka. Tako ce zapis algoritmaza zbrajanje biti jednostavniji.

    Ako oba broja na ulazu imaju n znamenaka, rezultat moze imati najvise n + 1 zna-menaka. Izlazne podatke cini niz znamenaka zbroja (cn+1, cn, cn1, . . . , c2, c1). U slucajukada zbroj ima samo n znamenaka, stavljamo cn+1 = 0. Racun opcenito izgleda ovako:

    an an1 a2 a1+ bn bn1 b2 b1cn+1 cn cn1 c2 c1

    Zbrajanje pocinjemo zdesna, od znamenaka jedinica. U prvom koraku racunamo a1 + b1 irezultat zapisemo na mjesto c1. U uvodnom primjeru imamo a1 = 5 i b1 = 2, pa je c1 = 7.

    Kad bismo algoritam za zbrajanje zeljeli analizirati do najjednostavnijih koraka, mogibismo se upitati otkud znamo da je 5+2 = 7? Takve male zbrojeve mozemo izracunati naprste, no tijekom skolovanja zapamtili smo sve moguce zbrojeve znamenaka. Mozemo,

    1

  • 2 POGLAVLJE 1. POJAM ALGORITMA

    dakle, reci da znamenke zbrajamo prema ovoj tablici:

    + 0 1 2 3 4 5 6 7 8 90 0 1 2 3 4 5 6 7 8 91 1 2 3 4 5 6 7 8 9 102 2 3 4 5 6 7 8 9 10 113 3 4 5 6 7 8 9 10 11 124 4 5 6 7 8 9 10 11 12 135 5 6 7 8 9 10 11 12 13 146 6 7 8 9 10 11 12 13 14 157 7 8 9 10 11 12 13 14 15 168 8 9 10 11 12 13 14 15 16 179 9 10 11 12 13 14 15 16 17 18

    U drugom koraku racunamo 4 + 9 = 13, no na mjesto c2 pisemo samo znamenku 3.Znamenku desetice prenosimo u treci korak (pisem 3, pamtim 1). Radi jednostavnijegzapisa razdvojit cemo tablicu zbrajanja znamenaka na tablicu zbrojeva (koje potpisujemoispod trenutacnih znamenaka pribrojnika) i na tablicu prijenosa (koje pamtimo za sljedecikorak, odnosno zabiljezimo iznad odgovarajucih znamenaka pribrojnika). Dakle, imamoove dvije tablice:

    Zbroj 0 1 2 3 4 5 6 7 8 90 0 1 2 3 4 5 6 7 8 91 1 2 3 4 5 6 7 8 9 02 2 3 4 5 6 7 8 9 0 13 3 4 5 6 7 8 9 0 1 24 4 5 6 7 8 9 0 1 2 35 5 6 7 8 9 0 1 2 3 46 6 7 8 9 0 1 2 3 4 57 7 8 9 0 1 2 3 4 5 68 8 9 0 1 2 3 4 5 6 79 9 0 1 2 3 4 5 6 7 8

    Prijenos 0 1 2 3 4 5 6 7 8 90 0 0 0 0 0 0 0 0 0 01 0 0 0 0 0 0 0 0 0 12 0 0 0 0 0 0 0 0 1 13 0 0 0 0 0 0 0 1 1 14 0 0 0 0 0 0 1 1 1 15 0 0 0 0 0 1 1 1 1 16 0 0 0 0 1 1 1 1 1 17 0 0 0 1 1 1 1 1 1 18 0 0 1 1 1 1 1 1 1 19 0 1 1 1 1 1 1 1 1 1

    Na unose u tablicama pozivat cemo se s pomocu uglatih zagrada. Tako je npr. Zbroj[4, 9] =3 i Prijenos[4, 9] = 1 jer je 4 + 9 = 13.

    U trecem koraku zbrajamo znamenke a3 = 3, b3 = 4 i dodajemo im prijenos izprethodnog koraka. Taj prijenos moze biti samo 0 ili 1, zato nam je jednostavnije modifi-cirati tablice zbrajanja nego ih pozivati vise puta. Ako je prijenos iz prethodnog koraka 0,

  • 3koristimo gore navedene tablice, a ako je prijenos 1 ove modificirane tablice:

    Zbroj2 0 1 2 3 4 5 6 7 8 90 1 2 3 4 5 6 7 8 9 01 2 3 4 5 6 7 8 9 0 12 3 4 5 6 7 8 9 0 1 23 4 5 6 7 8 9 0 1 2 34 5 6 7 8 9 0 1 2 3 45 6 7 8 9 0 1 2 3 4 56 7 8 9 0 1 2 3 4 5 67 8 9 0 1 2 3 4 5 6 78 9 0 1 2 3 4 5 6 7 89 0 1 2 3 4 5 6 7 8 9

    Prijenos2 0 1 2 3 4 5 6 7 8 90 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 1 12 0 0 0 0 0 0 0 1 1 13 0 0 0 0 0 0 1 1 1 14 0 0 0 0 0 1 1 1 1 15 0 0 0 0 1 1 1 1 1 16 0 0 0 1 1 1 1 1 1 17 0 0 1 1 1 1 1 1 1 18 0 1 1 1 1 1 1 1 1 19 1 1 1 1 1 1 1 1 1 1

    Dakle, u trecem koraku pisemo znamenku c3 = Zbroj2[3, 4] = 8 i pamtimoPrijenos2[3, 4] =0. Analogno nastavljamo dalje.

    Zapisimo sada sto radimo u i-tom koraku algoritma. Neka p oznacava prijenos izprethodnog koraka. Ako je p = 0, znamenku ci i prijenos za sljedeci korak uzimamo iztablica Zbroj i Prijenos, a u slucaju p = 1 koristimo tablice Zbroj2 i Prijenos2. Tomozemo zapisati ovako:

    ako je p = 0 onda[ci = Zbroj[ai, bi]p = Prijenos[ai, bi]

    inace[ci = Zbroj2[ai, bi]p = Prijenos2[ai, bi]

    Ovo ponavljamo za i = 1, 2, . . . , n. U prvom koraku nema prijenosa pa stavljamo p = 0,a na kraju definiramo cn+1 kao prijenos iz iz n-tog koraka. Zapis cijelog algoritma izgledaovako:

    p = 0za i = 1, . . . , n ponavljaj

    ako je p = 0 onda[ci = Zbroj[ai, bi]p = Prijenos[ai, bi]

    inace[ci = Zbroj2[ai, bi]p = Prijenos2[ai, bi]

    cn+1 = p

    Sada kad smo upoznali jedan primjer algoritma, mozemo istaknuti neke opce znacajketog pojma. Opcenito, algoritam je postupak za rjesavanje neke klase problema. Pojedineprobleme iz te klase nazivamo instancama. Na pocetku poglavlja prisjetili smo se algo-ritma za zbrajanje prirodnih brojeva kroz instancu 6247345 + 98492 problema zbrajanja.

    Svaki algoritam uzima neke ulazne podatke; oni odreduju instancu problema na kojiga primjenjujemo. Na kraju rada vraca izlazne podatke, koji predstavljaju rjesenje togproblema. Kod algoritma za zbrajanje ulazni podaci su pribrojnici, a izlazni podaci njihovzbroj.

  • 4 POGLAVLJE 1. POJAM ALGORITMA

    Algoritam staje nakon konacno mnogo koraka, za svaku instancu problema kojegrjesava. Nije tesko napisati niz naredbi koji bi se izvodio beskonacno, ali takve programene smatramo opisima algoritama. Nas algoritam za zbrajanje staje nakon n koraka akosu na ulazu n-znamenkasti brojevi (ne racunajuci prvo i zadnje pridruzivanje).

    Svaki korak od kojeg se sastoji algoritam je precizno i jednoznacno odreden. U praksimozemo imati jednostavnije ili kompliciranije korake, no bitno je da ih covjek ili stroj kojiizvodi algoritam moze izvrsavati tocno i bez dvosmislenosti.

    Slika 1.1: Al-Khwarizmi (oko 790 840 g.)1.

    Rijec algoritam potjece od perzijskog matematicara, astronoma i geografa iz 9.stoljeca al-Khwarizmija (puno ime u engleskoj transkripciji glasi Muhammad ibn Musaal-Khwarizmi). Napisao je knjigu u kojoj je opisao postupke za racunanje u indijskombrojevnom sustavu. Original na arapskom nije sacuvan, a latinski prijevod prosirio eu-ropom pod naslovom Algoritmi de numero Indorum (Al-Khwarizmi o indijskim broje-vima). Prema tom naslovu postupke za sustavno rjesavanje problema danas nazivamoalgoritmima. Stariji naziv algorizam ponekad se koristi u uzem, aritmetickom smislu2.

    Al-Khwarizmi napisao je jos jednu iznimno vaznu knjigu, Hisab al-jabr wal-muqabala,u kojoj se bavi rjesavanjem linearnih i kvadratnih jednadzbi. Matematicka disciplina alge-bra dobila je ime po drugoj rijeci iz tog naslova. S danasnjeg stanovista problemi kojima seal-Khwarizmi bavi mogu se ciniti trivijalnim. Medutim, tehniku njihovog rjesavanja dugu-jemo upravo Al-Khwarizmiju: postavimo problem u obliku algebarskih jednadzbi i prim-jenjujemo unaprijed zadana pravila da bismo dosli do rjesenja. Trivijalizacija problemakoji se svode na linearne ili kvadratne jednadzbe posljedica je duboke algoritmizacijematematike. Formula za rjesenja kvadratne jednadzbe

    x1,2 =bb2 4ac

    2a

    zapravo je sazet opis algoritma kojim od koeficijenata jednadzbe ax2+bx+c = 0 dolazimodo njezinih rjesenja.

    1Slika je preuzeta s web stranice [19].2U Klaicevom rjecniku stranih rijeci [14] algoritam se definira kao pravilan postupak pri racunanju.

  • 5Vratimo se algoritmima za osnovne aritmeticke operacije. U skoli smo osim algoritmaza zbrajanje naucili algoritme za oduzimanje, mnozenje, dijeljenje, mozda cak i algoritamza racunanje priblizne vrijednosti drugog korijena. Mnoga djeca ne vole matematikuupravo zbog inzistiranja na mehanickom savladavanju takvih racunskih rutina3.

    Cilj ove skripte nije ucenje izabranih algoritama napamet, nego razvijanje sposobnostirazumijevanja i kreiranja novih algoritama. Za to nam je nuzna vjestina preciznog zapi-sivanja algoritama i citanja s razumijevanjem algoritama koji je netko drugi napisao.Po misljenju autora, da bi se to savladalo potrebno je upoznati neke vazne algoritmei samostalno rijesiti odreden broj zadataka u kojima se trazi razvijanje algoritma zaneki problem. Citatelje takoder poticemo da algoritme koje cemo upoznati pokusajuimplementirati u nekom programskom jeziku. Pritom treba savladati odredene tehnickeprepreke, ali na taj nacin alogitmi ozive i dobiva se mogucnost testiranja, isprobavanjas raznim ulaznim podacima i jednostavnog modificiranja algoritama. Izbor programskogjezika manje je vazan. Koristit cemo uglavnom naredbe i koncepte koji postoje u svima,ili barem u vecini programskih jezika4.

    Zadaci

    Zadatak 1.1. Dokazite da zbrajanjem dvaju n-znamenkastih prirodnih brojeva dobivamobroj s najvise n+ 1 znamenaka.

    Zadatak 1.2. Zapisite algoritam za mnozenje prirodnih brojeva naucen u osnovnoj skoli!Koraci algoritma mogu biti slozenijih od onih koje smo koristili u zapisu algoritma zazbrajanje, npr. mozete koristiti zbrajanje viseznamenkastih brojeva kao poznatu operaciju.

    Zadatak 1.3. Na slican nacin zapisite algoritam za dijeljenje prirodnih brojeva naucenu osnovnoj skoli.

    Zadatak 1.4. Sjetite se i zapisite algoritam za rucno vadenje drugog korijena, u kojemse znamenke grupiraju po dvije.

    Zadatak 1.5. Pokusajte izmisliti i zapisati alternativne algoritme za osnovne racunskeoperacije, razlicite od onih koje ste naucili u skoli.

    3U americkom skolskom kurikulumu Everiday mathematics djecu se potice da razviju vlastite pos-tupke za racunanje i upoznaje ih se s alternativnim algoritmima za osnovne aritmeticke operacije; vidi [25].

    4Prethodnih akademskih godina na vjezbama iz kolegija Osnove algoritama zadaci su se radili uprogramskim jezicima C, Pascal i Python.

  • 6 POGLAVLJE 1. POJAM ALGORITMA

  • Poglavlje 2

    Brojevni sustavi

    Razvoj sustava za zapisivanje brojeva mozemo smatrati pocetkom matematike. Jedan odnajranijih poznatih sustava razvili su Babilonci oko 2000 godine prije Krista. Danasnjinacin zapisivanja brojeva potjece iz Indije i vjerojatno je nastao krajem 6. stoljeca.Ponekad se takvi brojevi nazivaju arapskim, jer su ih u srednjem vijeku Arapi donijeliu Europu. Taj je sustav zapisivanja brojeva omogucio razvoj algoritama za racunanjeo kojima smo govorili u prethodnom poglavlju. U drugom poznatom sustavu, rim-skom aditivno-suptraktivnom sustavu, racunanje je vrlo nespretno. Pokusajte direktnopomnoziti brojeve CXVII i XXIV!

    Slika 2.1: Znamenke u babilonskom brojevnom sustavu1.

    U indijsko-arapskom sustavu koristi se deset znamenaka 0, 1, 2, 3, 4, 5, 6, 7, 8 i9. Znacenje znamenaka ovisi o polozaju u zapisu broja, zato se takvi sustavi nazivajupozicionim. Naprimjer, zapis 2562 znaci 2 103+5 102+6 10+2 (prva i zadnja znamenka2 ne doprinose isto!). Istaknuta uloga broja 10 posljedica je cinjenice da ljudi imaju 10prstiju. Na isti nacin mozemo zapisivati brojeve koristeci se bilo kojim skupom od brazlicitih simbola, gdje je b 2 prirodan broj koji nazivamo bazom.

    1Slika je preuzeta s web stranice [20].

    7

  • 8 POGLAVLJE 2. BROJEVNI SUSTAVI

    Tijekom povijesti koristili su se i sustavi s bazom 20, a spomenuti babilonski sustavbio je pozicioni s bazom 60. Babilonci ipak nisu imali 60 razlicitih simbola, nego suznamenke zapisivali aditivno s pomocu dvaju simbola (vidi sliku 2.1). U racunarstvu suposebno pogodni sustavi kojima je baza potencija od 2. Sustav s bazom b = 2 naziva sebinarnim sustavom, sustav s bazom b = 3 ternarnim sustavom i tako dalje. Uobicajenisustav s bazom b = 10 zovemo dekadskim sustavom, a koriste se i oktalni sustav (b = 8) teheksadecimalni sustav (b = 16). Naprimjer, binarni broj (101101)2 znaci 1 25 + 0 24 + 1 23+1 22+0 2+1, a oktalni broj (2763)8 predstavlja 2 83+7 82+6 8+3. U sustavima sbazom manjom od 10 kao znamenke koristimo podskup uobicajenih dekadskih znamenaka.U heksadecimalnom sustavu trebamo 16 simbola, pa se uz dekadske znamenke koristimoslovima A, B, C, D, E i F koja redom predstavljaju brojeve od 10 do 15. Heksadecimalnibroj (7A9FE)16 znaci 7 164 + 10 163 + 9 162 + 15 16 + 14.

    Opcenito, u sustavu s bazom b skup simbola identificiramo s brojevima koje pred-stavljaju: {0, 1, 2, . . . , b 1}. Zapis (xkxk1 x1x0)b sa znamenkama xi iz tog skupapredstavlja broj xk bk + xk1 bk1 + . . . + x1 b + x0. S pomocu ove definicije brojevezapisane u bazi b lako mozemo prevesti u uobicajeni dekadski zapis.

    Primjer 2.1. Zapisimo brojeve (1011011)2, (123)4 i (BABA)16 u dekadskom sustavu.

    Rjesenje. Po definiciji, vrijedi (1011011)2 = 26 + 24 + 23 + 2 + 1 = 91. Kada u zapisu

    ne istaknemo bazu, podrazumijevat cemo da je dekadski (b = 10). Analogno dobivamo(123)4 = 1 42 + 2 4 + 3 = 27 i (BABA)16 = 11 163 + 10 162 + 11 16 + 10 = 47802.

    Valjanost pozicionih sustava pociva na cinjenici da se svaki prirodan broj moze najedinstven nacin zapisati u sustavu s bilo kojom bazom.

    Teorem 2.2. Neka je b 2 zadani prirodan broj. Za svaki prirodan broj n postojijedinstveni niz znamenaka (xk, . . . , x1, x0), xi {0, 1, . . . , b 1}, xk 6= 0, takav da jen = xk bk + . . .+ x1 b+ x0.

    Za dokaz ovog teorema trebat ce nam teorem o dijeljenju s ostatkom.

    Teorem 2.3 (o dijeljenju s ostatkom). Neka su m,n N prirodni brojevi. Tada postojejedinstveni brojevi k, o N0, o < n takvi da je m = k n+ o.

    Broj k zovemo kvocijentom ili kolicnikom, a broj o ostatkom dijeljenja. Zbog njihovejedinstvenosti mozemo uvesti oznake k = m div n i o = m mod n. Naprimjer, 17 div 5 =3 i 17 mod 5 = 2 jer je 17 = 3 5 + 2. Dokazimo sada teorem 2.2.Dokaz. Trebamo dokazati egzistenciju i jedinstvenost prikaza broja n u bazi b. Egzis-tenciju cemo dokazati konstruktivno, opisujuci algoritam za nalazenje trazenog prikaza.Oznacimo n0 = n i podijelimo taj broj s b. Kvocijent oznacimo n1, a ostatak x0:

    n0 = n1 b+ x0.

    Zatim podijelimo n1 s b uz kvocijent n2 i ostatak x1:

    n1 = n2 b+ x1.

  • 9Postupak analogno nastavimo dalje:

    n2 = n3 b+ x2,n3 = n4 b+ x3,

    ...nk = 0 b+ xk.

    Zaustavljamo se kada kvocijent postane 0. Svi daljnji kvocijenti ni i ostaci xi bili bi 0.Opisani postupak ovako mozemo zapisati u obliku algoritma:

    n0 = ni = 0dok je ni 6= 0 ponavljaj xi = ni mod bni+1 = ni div bi i+ 1

    Naredba i i+ 1 u zadnjem retku povecava vrijednost varijable i za jedan.Da bi ovo zaista bio dokaz egzistencije prikaza u bazi b, trebamo se uvjeriti da postupak

    staje nakon konacno mnogo koraka i da definira trazeni prikaz. Svaki sljedeci ni dobivamood prethodnog cjelobrojnim dijeljenjem s b 2. Jasno je da ce nakon konacno mnogokoraka rezultat biti 0 i tada algoritam staje. Jos treba provjeriti da su ostaci x0, . . . , xk {0, . . . , b1} zaista znamenke od n u bazi b. Pretpostavimo da smo nakon k koraka dobilikvocijent nk+1 = 0. U prethodnom koraku definirali smo nk = nk+1 b+xk = 0b+xk = xk.Supstitucijom u prethodne korake dobivamo redom

    nk1 = nk b+ xk1 = xk b+ xk1,nk2 = nk1 b+ xk2 = (xk b+ xk1) b+ xk1 = xk b2 + xk1 b+ xk2,

    ...

    n0 = n1 b+ x0 = (xk bk1 + . . .+ x1) b+ x0 = xk bk + . . .+ x1 b+ x0.

    Vidimo da n = n0 ima prikaz (xk x1x0)b. Sada jos treba provjeriti jedinstvenost togprikaza. Pretpostavimo da n ima jos jedan prikaz (yl y1y0)b. Tada je n = (xk bk1 +. . . + x1) b + x0 = (yl bl1 + . . . + y1) b + y0. Podijelimo li taj izraz cjelobrojno s b,zbog jedinstvenosti u teoremu o dijeljenju s ostatkom dobivamo da je x0 = y0 = n mod bi xk bk1 + . . .+ x2 b+ x1 = yl bl1 + . . .+ y2 b+ y1 = n div b. Posljednji izraz ponovodijelimo s b i dobivamo x1 = y1 i tako dalje. Buduci da su sve znamenke jednake (xi = yi,i = 0, 1, 2, . . . ), vodeca nenul znamenka se takoder podudara pa su zapisi jednake duljine(k = l). Ta se duljina moze izraziti kao funkcija od n i od b, sto ostavljamo citateljimakao zadatak.

    Kroz ovaj dokaz ujedno smo dobili postupak kojim broj n zapisan u dekadskom sustavumozemo prevesti su sustav s bilo kojom bazom b. Algoritam iz dokaza izvodimo na papirutako da desno od broja n povucemo vertikalnu crtu i uzastopno ga dijelimo s bazom.Ostatke dijeljenja pisemo desno od crte, a kvocijente lijevo, jedan ispod drugog.

  • 10 POGLAVLJE 2. BROJEVNI SUSTAVI

    Primjer 2.4. Zapisimo broj n = 3761 u sustavu s bazom b = 7.

    Rjesenje. Dijeljenjem sa 7 dobivamo kvocijent 537 i ostatak 2.

    3761 2537

    Zatim podijelimo 537 sa 7, kvocijent 76 napisemo ispod, a ostatak 5 desno od crte:

    3761 2537 576

    Nastavimo dijeliti sa 7, rezultate pisati ispod, a ostatke desno.

    3761 2537 576 610 31 10

    Kada dobijemo nulu, procitamo ostatke odozdo prema gore i imamo zapis n = (13652)7.

    Broj zapisan u bazi b1 mozemo prevesti u bazu b2 tako da ga najprije zapisemo udekadskom sustavu, a zatim prebacimo u bazu b2 algoritmom koji smo upoznali. Ako sub1 i b2 potencije istog broja, to mozemo uciniti efikasnije grupiranjem ili prosirivanjemznamenaka.

    Primjer 2.5. Zapisimo binarni broj (10110111101)2 u oktalnom sustavu.

    Rjesenje. Najprije znamenke grupiramo po 3 zdesna na lijevo:

    10|110|111|101 2 6 7 5

    Istaknute nizove triju binarnih znamenaka prevodimo u po jednu oktalnu: 000 0,001 1, 010 2, . . . , 111 7. Vodecu grupu znamenaka 10 tretiramo kao 010. Takodobivamo zapis (2675)8.

    Primjer 2.6. Zapisimo heksadecimalni broj (2A9)16 u binarnom sustavu.

    Rjesenje. Svaku heksadecimalnu znamenku prevodimo u niz od 4 binarne znamenke: 00000, 1 0001, 2 0010, . . . , 9 1001, A 1010, . . . , F 1111. Vodece nule prvogpo redu niza zanemarujemo. Tako dolazimo do zapisa (1010101001)2.

  • 11

    Primjer 2.7. Zapisimo oktalni broj (6251)8 u heksadecimalnom sustavu.

    Rjesenje. Prvo oktalni broj pretvorimo u binarni:

    6 2 5 1

    110|010|101|001

    Zatim grupiramo binarne znamenke po cetiri i prevedemo ih u hekdadecimalne:

    1100|1010|1001 C A 9

    Dobili smo broj (CA9)16.

    Algoritmi za osnovne racunske operacije koje smo naucili u skoli funkcioniraju u sus-tavu s bilo kojom bazom. Postupci su potpuno analogni onima u dekadskom sustavu,samo treba prilagoditi tablice zbrajanja i mnozenja znamenaka. Naprimjer, u binarnomsustavu je (1)2 + (1)2 = (10)2 (pisem 0, pamtim 1).

    Primjer 2.8. Izracunajmo zbroj (12201)3 + (2121)3 u ternarnom sustavu.

    Rjesenje. Treba nam tablica zbrajanja ternarnih znamenaka:

    + 0 1 20 0 1 21 1 2 102 2 10 11

    Postupak izgleda ovako:

    1 1

    1 2 2 0 1+ 2 1 2 1

    2 2 0 2 2

    Rezultat je broj (22022)3.

    Primjer 2.9. Izracunajmo razliku (421314)5 (34123)5 u sustavu s bazom 5.

    Rjesenje. I za oduzimanje koristit cemo se tablicom zbrajanja znamenaka u bazi 5.

    + 0 1 2 3 40 0 1 2 3 41 1 2 3 4 102 2 3 4 10 113 3 4 10 11 124 4 10 11 12 13

  • 12 POGLAVLJE 2. BROJEVNI SUSTAVI

    Postupak pocinje isto kao u dekadskom sustavu:

    4 2 1 3 1 4 3 4 1 2 3

    1

    Oduzimamo najdesnije znamenke (4)5 (3)5 = (1)5 i rezultat pisemo ispod crte. Uiducem koraku trebali bismo oduzeti vecu znamenku od manje. Posudujemo jedinicusa sljedece pozicije i umjesto (1)5 (2)5 racunamo (11)5 (2)5. U tablici zbrajanjapronalazimo (2)5 + (4)5 = (11)5, pa je rezultat znamenka 4.

    2

    4 2 1 6 3 1 4 3 4 1 2 3

    4 1

    Sada zbog posudene jedinice ne racunamo (3)5 (1)5, nego (2)5 (1)5 = (1)5.

    2

    4 2 1 6 3 1 4 3 4 1 2 3

    1 4 1

    U iduca dva koraka takoder posudujemo jedinice sa sljedecih pozicija.

    3 1 2

    6 4 6 2 1 6 3 1 4 3 4 1 2 3

    3 3 2 1 4 1

    Rezultat je (332141)5.

    Primjer 2.10. Izracunajmo umnozak (1011011)2 (1101)2 u binarnom sustavu.Rjesenje. Mnozenje je u binarnom sustavu posebno jednostavno jer su jedine znamenke 0i 1, pa nam tablice ne trebaju. Za svaku znamenku jedinice iz desnog faktora potpisujemolijevi faktor pomaknut odgovarajuci broj mjesta udesno.

    1 0 1 1 0 1 1 1 1 0 11 0 1 1 0 1 1

    1 0 1 1 0 1 10

    + 1 0 1 1 0 1 1

    1 0 0 1 0 0 1 1 1 1 1

    Zbrajanjem potpisanih brojeva dobivamo umnozak (10010011111)2.

  • 13

    Primjer 2.11. Izracunajmo umnozak (3122)4 (232)4 u sustavu s bazom 4.Rjesenje. Za ovaj racun trebaju nam tablice zbrajanja i mnozenja u bazi 4.

    + 0 1 2 30 0 1 2 31 1 2 3 102 2 3 10 113 3 10 11 12

    1 2 31 1 2 32 2 10 123 3 12 21

    Mnozimo (3122)4 s prvom znamenkom drugog faktora 2, zdesna na lijevo. U tablicinalazimo produkt znamenaka (2)4 (2)4 = (10)4, pisemo znamenku 0 i prenosimo 1 usljedeci korak. U drugom koraku racunamo (2)4 (2)4 + (1)4 = (11)4, pisemo 1 ponovoprenosimo 1. U trecem koraku pisemo (2)4 (1)4 + (1)4 = (3)4, a u cetvrtom (2)4 (3)4 =(12)4:

    1 1

    3 1 2 2 2 3 21 2 3 1 0

    Na slican nacin mnozimo (3122)4 sa znamenkom 3 i rezultat zapisujemo jedno mjestoudesno.

    1 1 1

    3 1 2 2 2 3 21 2 3 1 0

    2 2 0 3 2

    Na kraju ponovno mnozimo s 2 i zbrajamo tri produkta.

    3 1 2 2 2 3 21 2 3 1 0

    2 2 0 3 2+ 1 2 3 1 0

    2 1 3 0 2 3 0

    Rezultat je (2130230)4.

    Primjer 2.12. U binarnom sustavu podijelimo brojeve (100011)2 : (111)2.

    Rjesenje. Dijeljenje je jednostavnije u binarnom nego u dekadskom sustavu. Da bismoodredili prvu znamenku kvocijenta, moramo procijeniti koliko puta djelitelj stane upocetni niz znamenaka djeljenika. U binarnom sustavu odgovor moze biti samo 0 ili 1!

    1 0 0 0 1 1 : 1 1 1 = 1 1 1 1

    1 1

    Broj (111)2 oduzimamo od prve cetiri znamenke broja (100011)2 i zatim spustamosljedecu znamenku. Dobili smo broj (11)2 koji je manji od djelitelja, pa na rezultat

  • 14 POGLAVLJE 2. BROJEVNI SUSTAVI

    dijeljenja dodajemo 0 i spustamo jos jednu znamenku djeljenika.

    1 0 0 0 1 1 : 1 1 1 = 1 0 1 1 1

    1 1 1

    Sada djelitelj stane tocno jednom u (111)2 i vidimo da je kvocijent (101)2:

    1 0 0 0 1 1 : 1 1 1 = 1 0 1 1 1 1

    1 1 1

    1 1 10

    Osim prirodnih brojeva u sustavima s razlicitim bazama mozemo zapisivati cijele,racionalne i realne brojeve. Broj nula u svim sustavima zapisujemo kao 0. Zanimljivoje da u Babilonskom heksadecimalnom sustavu nije bilo posebnog simbola za nulu. Vri-jednost broja morala se pogadati iz konteksta i razmaka medu znamenkama. Negativnecijele brojeve zapisujemo na uobicajen nacin, sa znakom ispred zapisa. Naprimjer,(1100)2 je binarni zapis broja 12.

    Razlomci su omjeri cijelog i prirodnog broja i mozemo ih tako zapisivati. Drugamogucnost je da prosirimo pozicioni sustav i dozvolimo negativne potencije baze, analognodecimalnim brojevima2 u dekadskom sustavu. Decimalni zapis 27.69 predstavlja broj2 101 + 7 100 + 6 101 + 9 102. Opcenito, zapis (xk x1x0.x1 xm)b znacixk bk + . . . + x1 b1 + x0 b0 + x1 b1 + . . . + xm bm. Pritom su k,m N, axk, . . . , x0, . . . , xm {0, . . . , b 1} su znamenke.

    Primjer 2.13. Zapisimo razlomak 91/16 u binarnom sustavu.

    Rjesenje. Rjesenje mozemo dobiti tako da brojnik 91 = (1011011)2 i nazivnik 16 =(10000)2 zapisemo u binarnom sustavu i primijenimo algoritam za dijeljenje:

    1 0 1 1 0 1 1 : 1 0 0 0 0 = 1 0 1 1 0 0 0 0

    1 1 0 1 1

    1 0 0 0 01 0 1 1

    Dobili smo kvocijent (101)2 i ostatak (1011)2, koji nastavljamo dijeliti spustanjem nula.

    2Prema pravopisu decimalne brojeve trebali bismo pisati sa zarezom umjesto s tockom, tj. kao 27, 69.U ovoj knjizi ipak cemo se koristiti decimalnom tockom zbog citljivijeg zapisa nizova decimalnih brojeva.Pisat cemo 1.1, 1.2, 1.3. . . umjesto 1, 1, 1, 2, 1, 3. . . .

  • 15

    Znamenke koje dobivamo biljezimo iza znaka tocke.

    1 0 1 1 0 1 1 : 1 0 0 0 0 = 1 0 1 . 1 0 1 1 1 0 0 0 0

    1 1 0 1 1

    1 0 0 0 01 0 1 1 0

    1 0 0 0 01 1 0 0 0

    1 0 0 0 01 0 0 0 0

    1 0 0 0 00

    Rezultat je (101.1011)2. Alternativno, razlomak 91/16 = 51116

    mozemo zapisati u binarnomsustavu prevodeci posebno cjelobrojni dio 5, a zatim decimalni dio 11

    16. Za cjelobrojni

    dio koristimo algoritam uzastopnog dijeljenja s bazom, koji smo ranije upoznali:

    5 12 01 10

    Znamenke iza tocke dobivamo dualnim algoritmom. Pomnozimo brojnik 11 s bazom 2i cjelobrojno ga podijelimo s nazivnikom. Kvocijent 22 div 16 = 1 je prva znamenka i za-pisujemo ga desno od crte, a ostatak 22 mod 16 = 6 zapisujemo ispod i s njim nastavljamopostupak.

    11 16

    Produkt 2 6 = 12 daje rezultat 0 i ostatak 12 pri dijeljenju s nazivnikom 16.11 16 0

    12

    Nadalje, 2 12 = 24 daje rezultat 1 i ostatak 8 pri dijeljenju sa 16.11 16 0

    12 18 10

    U zadnjem koraku 2 8 = 16 djeljiv je bez ostatka s nazivnikom pa algoritam staje.Znamenke cjelobrojnog dijela pisemo od decimalne tocke ulijevo (redom kojim smo ihdobivali), a znamenke decimalnog dijela udesno: (101.1011)2.

  • 16 POGLAVLJE 2. BROJEVNI SUSTAVI

    U prethodnom primjeru razlomak ima konacni zapis. Kada razlomak do kraja skra-timo i u nazivniku ostane prosti faktor koji ne dijeli bazu, dobivamo beskonacni periodicnizapis.

    Primjer 2.14. Zapisimo razlomak 7/15 u ternarnom sustavu.

    Rjesenje. Koristimo se algoritmom uzastopnog mnozenja s bazom b = 3 i dijeljenja snazivnikom 15, kojeg smo upoznali u prethodnom primjeru.

    7 16 13 09 1

    12 26

    U petom koraku dobili smo ostatak 3 12 mod 15 = 6, koji smo vec imali u prvom koraku.To znaci da ce se u nastavku ponavljati niz ternarnih znamenaka 1012. Razlomak imazapis (0.11012101210121012 . . .)3, sto krace zapisujemo kao (0.11012)3 ili (0.11012)3.

    Pokazuje se da svi razlomci imaju beskonacne periodicne zapise. Konacni zapisshvacamo kao periodicni u kojem se ponavlja znamenka 0. Iracionalni brojevi kao

    2, pi

    i e i imaju beskonacne neperiodicne zapise u pozicionom sustavu s bilo kojom bazom. Uzodredeni tehnicki dogovor, svaki realan broj ima jedinstven zapis u sustavu s bazom b.

    Problem nastaje upravo zbog brojeva s konacnim zapisom. Naime, umjesto ponav-ljanja znamenke 0, broj mozemo zapisati ponavljanjem najvece znamenke b1. Naprimjer,broj 1 u dekadskom sustavu mozemo zapisati kao 1.000 . . . ili 0.999 . . .. Da bismo osiguralijedinstvenost zapisa drugu mogucnost zabranjujemo.

    Teorem 2.15. Neka je b 2 prirodan broj. Za svaki realan broj x > 0 postoji jedinstvenicijeli broj k i niz znamenaka xi {0, . . . , b 1}, i k takav da je xk 6= 0, x =

    ik

    xi bi ida ne postoji m takav da je xi = b 1 za sve i m.

    Nulu zapisujemo kao 0, a negativne realne brojeve s pomocu znaka . Dokaz ovogteorema za b = 10 nalazi se u knjizi [21] na str. 35 (teorem 2).

    Za racunanje s realnim brojevima zapisanim na ovaj nacin koristimo iste algoritmekao za prirodne brojeve. Pritom zapis ogranicavamo na konacan broj znamenaka kako bialgoritmi stali u konacno mnogo koraka. Kod zbrajanja pazimo da pribrojnike potpisemos tockom na odgovarajucim mjestima, kod mnozenja je broj znamenaka iza tocke u pro-duktu jednak zbroju broja znamenaka iza tocke u faktorima itd. Neke probleme koji nas-taju zbog ogranicenja na konacan broj znamenaka upoznat cemo u poglavlju o prikazubrojeva u racunalu.

    Zadaci

    Zadatak 2.1. Opisite algoritam za zbrajanje brojeva u rimskom brojevnom sustavu.

  • 17

    Zadatak 2.2. Dokazite teorem o dijeljenju s ostatkom.

    Zadatak 2.3. Napisite formulu za broj znamenaka prirodnog broja n u zapisu s bazom b.

    Zadatak 2.4. Zapisite brojeve (100110111)2, (1201221)3, (42310)5, (2147)8 i (DEDA)16u dekadskom sustavu.

    Zadatak 2.5. Zapisite dekadski broj 5790 u sustavima s bazom 2, 3, 8 i 16.

    Zadatak 2.6. Grupiranjem znamenaka pretvorite heksadecimalni broj (8D6E)16 u oktalnisustav.

    Zadatak 2.7. Zbrojite direktno, bez pretvaranja u dekadski sustav (1111011)2 + (10110)2,(122)3 + (211)3 + (101)3 + (120)3 + (222)3 i (BABA)16 + (DEDA)16.

    Zadatak 2.8. Oduzmite direktno, bez pretvaranja u dekadski sustav (110011011)2(110110)2i (1302)4 (123)4.Zadatak 2.9. Pomnozite direktno, bez pretvaranja u dekadski sustav (1101)2 (101)2 i(21201)3 (1022)3.Zadatak 2.10. Podijelite direktno, bez pretvaranja u dekadski sustav (110323)5 : (401)5i (1101)2 : (110)2.

    Zadatak 2.11. Precizno zapisite algoritme za zbrajanje, oduzimanje, mnozenje i dijel-jenje u binarnom sustavu.

    Zadatak 2.12. Zapisite brojeve (102.21)3, (0.4)7 i (3.032)5 kao razlomke i kao decimalnebrojeve u sustavu s bazom 10.

    Zadatak 2.13. Zapisite dekadski broj 17.3125 u binarnom i u ternarnom sustavu.

    Zadatak 2.14. Precizno zapisite algoritam za pretvaranje razlomka manjeg od 1 u sustavs bazom b uzastopnim mnozenjem s bazom i dijeljenjem s nazivnikom, opisan u primje-rima 2.13 i 2.14.

    Zadatak 2.15. Prosirivanjem i grupiranjem znamenaka pretvorite broj (123.4567)8 usustav s bazom 2 te brojeve (10111011.101)2 i (443.5274)8 u sustav s bazom 16.

    Zadatak 2.16. Odredite bazu b takvu da broj (235)b+1 bude dvostruko veci od broja (141)b.

    Zadatak 2.17. Odredite sesteroznamenkasti broj u sustavu s bazom 5 kojemu je zadnjaznamenka 2 i koji se poveca dva puta kad zadnju znamenku premjestimo na prvo mjesto.Rezultat zapisite u sustavu s bazom 5.

    Zadatak 2.18. Odredite bazu b u kojoj je moguc racun (11x)b + (x3y)b = (3y0)b, za nekeznamenke x i y.

    Zadatak 2.19. Neka je b 2 prirodan broj. Zapisite brojeve (bbb)b2 i (b.b)b2 u sustavu sbazom b.

  • 18 POGLAVLJE 2. BROJEVNI SUSTAVI

    Zadatak 2.20. Dokazite da se svaki prirodan broj n moze na jedinstven nacin prikazatiu obliku n = xk k! + xk1 (k 1)! + . . . + x2 2! + x1 1!, pri cemu su znamenkexi {0, 1, . . . , i}, i = 1, . . . , k te vrijedi xk 6= 0. Pisemo n = (xkxk1 x2x1)!. To jetakozvani faktorijelski brojevni sustav.

    Zadatak 2.21. Fibonaccijevi brojevi definirani su s F0 = 0, F1 = 1 i s rekurzijom Fk+1 =Fk + Fk1 za k N. Dokazite da se svaki prirodan broj n moze prikazati kao zbrojmedusobno razlicitih Fibonaccijevih brojeva n = Fk1 +Fk2 + . . .+Fkr . Ako zahtjevamo dapritom vrijedi ki+1 ki 2, i = 1, . . . , r 1 i kr 2, takav prikaz je jedinstven. Ovajnacin prikazivanja brojeva naziva se Fibonaccijevim brojevnim sustavom.

  • Poglavlje 3

    Nacini zapisivanja algoritama

    U prethodnom poglavlju upoznali smo algoritme za osnovne aritmeticke operacije i zaprevodenje brojeva iz baze u bazu. Neke od tih algoritama nastojali smo precizno zapisati,dok smo druge opisali neformalno ili smo ih objasnili kroz primjere i zadatke. Taj jepristup prikladniji kod poducavanja. Ne bi bilo mudro skolsku djecu uciti zbrajanje takoda im se na plocu napise algoritam iz prvog poglavlja.

    Potreba za preciznim zapisivanjem algoritama pojavila se s razvojem racunskih stro-jeva. U prvoj polovici 19. stoljeca engleski matematicar, inzenjer i izumitelj CharlesBabbage projektirao je prvo univerzalno racunalo, sposobno izvoditi razlicite proracuneovisno o programu koji se u njega unese. Babbage je stroj nazvao Analytical engine ido kraja zivota nije ga uspio izgraditi. Ipak, u suradnji s Adom Lovelace1 razvijao je prveprograme za svoj mehanicki kompjuter. Mnogo kasnije programski jezik Ada nazvan jepo prvoj programerki Adi Lovelace.

    Sredinom 20. stoljeca izgradena su prva elektronicka racunala. Tehnologiju elektron-skih cijevi ubrzo su zamijenili tranzistori, a u 70-tim godinama poluvodicki integriranikrugovi. S minijaturizacijom racunala postaju sve brza i sve mocnija. Svjedoci smo da setaj proces nastavlja i danas.

    Prva elektronicka racunala programirala su se u strojnom jeziku, naredbama kojeizvodi procesor. Kao pomoc u programiranju razvijeni su tzv. asembleri, programi kojiprevode simbolicke naredbe u strojne i pomazu pri adresiranju memorije. Stoga se takviprogramski jezici nazivaju i asemblerskim jezicima.

    Prvi visi programski jezik bio je FORTRAN (od engleskog FORmula TRANslator),razvijen 1954. Jos neki od ranih programskih jezika iz tog doba su LISP, Cobol, Algol iBasic. Da bi se programi pisani u tim jezicima mogli izvoditi na racunalu, potrebno ih jenajprije prevesti na strojni jezik. To se radi s pomocu posebnih programa prevoditelja ilikompilatora (eng. compiler). Jedna naredba viseg programskog jezika tipicno se prevodiu vise strojnih naredbi.

    U 70-tim godinama 20. stoljeca razvijeni su mnogi specijalizirani programski jezici.Programski jezik Pascal razvijen je za ucenje strukturiranog programiranja. Programskijezik C originalno je razvijen za sistemsko programiranje, zajedno s operacijskim sustavomUnix. Oba su postala vrlo popularna i C se do danas koristi za mnoge druge svrhe. Iz

    1Augusta Ada King, vojvotkinja od Lovelacea, bila je matematicarka i kci poznatog pjesnika lordaByrona.

    19

  • 20 POGLAVLJE 3. NACINI ZAPISIVANJA ALGORITAMA

    tog razdoblja potjecu i prvi objektno orijentirani programski jezici Simula i Smalltalk.Razvoj novih programskih jezika i novih inacica postojecih nastavljen je u 80-tim i

    90-tim godinama. Godine 1983. definiran je vec spomenuti programski jezik Ada, s ciljemstandardizacije softvera pisanog za Ministarstvo obrane Sjedinjenih americkih drzava. Istegodine razvijen je C++, objektno orijentirana inacica jezika C. Godine 1987. razvijen jeskriptni jezik Perl, a 1991. Python. Takvi jezici ne prevode se s pomocu kompilatora, negoih izvodi takozvani interpreter, program koji paralelno prevodi i izvodi naredbe. Takoder,1991. godine razvijen je jezik Java koji je postao popularan za pisanje aplikacija za web.U 90-tim godinama sve je vise programskih jezika namijenjenih za internet, naprimjerPHP razvijen 1995. godine.

    Za buduce nastavnike vazni su edukacijski programski jezici namijenjeni djeci. Jedanod najpoznatijih je LOGO, razvijen 1967. i poznat po takozvanoj kornjacinoj grafici.Od 2007. godine slobodno je dostupan programski jezik Scratch [23] razvijen na MIT-u. Postoje inacice za razne operacijske sustave i na hrvatskom jeziku. Scratch takoderomogucuje kornjacinu grafiku, ali i puno vise od toga. Zanimljiv je zato sto se programirabez pisanja, slaganjem pravokutnika i okvira s naredbama (vidi sliku 3.1).

    Vrlo rano uocena je potreba zapisivanja algoritama u jednostavnom i preglednomobliku, citljivijem od koda pisanog u nekom programskom jeziku. Jedan od nacina sudijagrami toka, poput onog na slici 3.2. Dijagrami toka vizualno su atraktivni, ali zahti-

    Slika 3.1: Programski jezik Scratch.

  • 21

    Pocetak

    ?

    Ucitaja i b

    ?

    c = bb = a mod ba = c

    ?

    @@@@@

    @@

    @@@

    Da li jeb = 0?

    Ne

    Da

    ?

    Ispisi a

    ?

    Kraj

    Slika 3.2: Primjer dijagrama toka.

    jevaju puno prostora i zato ih necemo koristiti u ovoj skripti. Algoritme cemo zapisivatiu takozvanom pseudojeziku.

    Vecina programskih jezika ima mnostvo zajednickih znacajki. Ilustrirat cemo ih naprimjerima jezika FORTRAN, Pasca, C i Python. U ta cetiri jezika, kao i u skoro svimostalim, ulazni podaci, medurezultati i rezultati proracuna pohranjuju se u varijablama.Na pocetku programa potrebno je deklarirati varijable, tj. odrediti koji ce se tip podatakau njima spremati (npr. cijeli brojevi integeri, realni brojevi, znakovi ili nizovi znakovai dr.). Programski jezik Python po tome je nesto drugaciji. U njemu se varijable nedeklariraju, ali ih je prije prve upotrebe potrebno inicijalizirati, tj. pridruziti im nekuvrijednost. Time se ujedno odreduje koji je tip podataka spremljen u pojedinoj varijabli.Deklaracija i inicijalizacija varijabli radi se u nasa cetiri ogledna programska jezika nasljedeci nacin.

  • 22 POGLAVLJE 3. NACINI ZAPISIVANJA ALGORITAMA

    Deklaracija / inicijalizacija varijabli i pridruzivanje

    FORTRAN Pascal

    INTEGER m,n var m,n:integer;

    REAL x,y x,y:real;

    x = 3.14 x := 3.14;

    y = SIN(x) - x**3 y := sin(x) - x*x*x;

    m = 49 / 21 m := 49 div 21;

    n = MOD(49,21) n := 49 mod 21;

    C Python

    int m,n; m = n = 0

    float x,y; x = y = 0.0

    x = 3.14; x = 3.14

    y = sin(x) - pow(x,3); y = math.sin(x) - x**3

    m = 49 / 21; m = 49 / 21

    n = 49 % 21; n = 49 % 21

    Ovdje smo ujedno vidjeli kako se varijablama pridruzuju konstante ili rezultati nekihracunskih operacija.

    Kao sto smo objasnili, svaki algoritam na pocetku uzima ulazne podatke, a na krajuvraca izlazne podatke koji predstavljaju rjesenje problema. Zato svi programski jeziciimaju naredbe za ulaz i za izlaz podataka.

    Ulaz i izlaz podataka

    FORTRAN Pascal

    PRINT *,Unesi prirodan broj writeln(Unesi prirodan broj);

    READ *,n read(n);

    C Python

    printf("Unesi prirodan broj\n"); print "Unesi prirodan broj"

    scanf("%d",&n); n = input()

    Programi su nizovi naredbi i izvode se redom kojim su napisani. Cesto je potrebnodio programa izvesti ili ne izvesti, ovisno o nekom uvjetu. To nam omogucuje naredba zagrananje.

  • 23

    Grananje

    FORTRAN Pascal

    if (n=0 and m0) then

    IF ((n.EQ.0).AND.(m.NE.0)) THEN begin...

    ...ENDIF end;

    C Python

    if (n==0 && m!=0) if n==0 and m!=0:

    { naredba unutar if...

    ...} naredba nakon if

    Takoder, cesto je potrebno dio programa izvesti vise puta. Zato u programskim jezicimapostoje naredbe za ponavljanje, tzv. petlje.

    Ponavljanje

    FORTRAN Pascal

    for i:=1 to n do

    DO 10 i=1,n begin...

    ...10 CONTINUE end;

    10 IF (n.GT.0) THEN while (n>0) do... begin

    GOTO 10...

    ENDIF end;

    C Python

    for (i=0; i0) while n>0:

    { naredba unutar while...

    ...} naredba nakon while

  • 24 POGLAVLJE 3. NACINI ZAPISIVANJA ALGORITAMA

    Nasa cetiri programska jezika dozvoljavaju indeksirane varijable, takozvane nizove ilipolja (eng. arrays).

    Nizovi

    FORTRAN Pascal

    INTEGER a(0:99) var a:array [0..99] of integer;

    DO 10 i=0,99 for i:= 0 to 99 do

    10 a(i) = 2*i+1 a[i] := 2*i+1;

    C Python

    int a[100]; a = [0] * 100

    for (i=0; i

  • 25

    C Python

    /* Aritmeticka sredina */ # Aritmeticka sredina

    float sredina(float x, float y) def sredina(x,y):

    { return (x+y)/2; return (x+y)/2.0

    }

    Pseudojezik objedinjuje zajednicke znacajke ovih cetiriju i mnogih drugih program-skih jezika. Omogucuje nam manje formalno zapisivanje algoritama, prilagodeno ljudimaumjesto racunalima. Nadedbe cemo pisati na hrvatskom, slicno kao u zapisu algoritmaza zbrajanje iz prvog poglavlja i algoritma iz dokaza teorema 2.2. U iducem poglavljupreciznije cemo opisati pseudojezik i koristit cemo ga u nastavku za zapisivanje raznihalgoritama. Programe pisane u pseudojeziku lako je prevesti na neki pravi programskijezik. Savjetujemo citateljima da to rade paralelno s citanjem ove skripte.

    Zadaci

    Zadatak 3.1. Istrazite sto radi algoritam prikazan dijagramom toka na slici 3.2.

    Zadatak 3.2. Zapisite s pomocu dijagrama toka algoritam za zbrajanje iz prvog poglavljate algoritam iz dokaza teorema 2.2.

    Zadatak 3.3. U programskom jeziku Pascal napisite program Hello world, koji ispisujeporuku na ekranu:

    PROGRAM hello(input, output);

    BEGIN

    writeln(Hello, world!);

    END.

    Prevedite ga s pomocu nekog kompilatora za Pascal i pokrenite. Besplatno dostupni kom-pilatori za Pascal su npr. Free Pascal [7] i GNU Pascal [11].

    Zadatak 3.4. Napisite program Hello world u programskom jeziku C :

    #include

    main()

    { printf("Hello, world!\n");

    }

    Prevedite ga s pomocu nekog kompilatora za C i pokrenite. Besplatno dostupni kompilatoriza C su npr. GCC [8] i Dev-C++ [2].

    Zadatak 3.5. Napisite program Hello world u programskom jeziku Python i pokrenitega s pomocu odgovarajuceg interpretera:

    print "Hello, world!"

    Interpreteri i dokumentacija za Python besplatno su dostupni na web stranici [22].

  • 26 POGLAVLJE 3. NACINI ZAPISIVANJA ALGORITAMA

    Zadatak 3.6. Instalirajte programski jezik Scratch [23] i poigrajte se s njime. Natjerajtemacu da govori Hello, world, mijauce, hoda po ekranu i crta s pomocu kornjacinegrafike.

  • Poglavlje 4

    Pseudojezik

    Da bismo algoritam mogli izvoditi na racunalu, moramo ga kodirati u nekom program-skom jeziku. Kod mora biti potpuno u skladu sa sintaksom izabranog formalnog jezikai algoritam mora biti do kraja precizno opisan, cak i detalji koji nam se cine jasnima izkonteksta.

    Ako je nas algoritam namijenjen za citanje ljudima, mozemo ga zapisati na manjeformalan nacin. Mozemo si dozvoliti slobodniju sintaksu i detaljno raspisati samo bitnedijelove algoritma. Takav nacin zapisivanja algoritama naziva se pseudojezik ili pseudokod.

    Pseudojezik se koristi u mnogim knjigama i clancima koji se bave algoritmima, alizapravo ne postoji standardna verzija pseudojezika. Ovisno o kontekstu koristi se sazetijiili detaljniji nacin zapisivanja algoritama. Dijelove algoritma mozemo zamijeniti pojedi-nacnim naredbama, opisati ih prirodnim jezikom, ili ih raspisati do u detalje kao u pravomprogramskom jeziku. U ovom poglavlju upoznat cemo se sa stilom pisanja pseudokodakoji cemo koristiti u nastavku skripte. U pravilu cemo algoritme zapisivati dosta detaljno,tako da ih se lako moze prevesti na neki pravi programski jezik.

    Algoritam, odnosno racunalni program, sastoji se od niza naredbi koje se izvode redomkojim su napisane. U pseudojeziku za naredbe koristimo hrvatske rijeci. Zapisujemo ihuspravnim slovima, jednu ispod druge. Ponekad je potrebno grupirati nekoliko uzastopnihnaredbi u jednu cjelinu, sto cinimo uglatim zagradama: prva naredbadruga naredba

    treca naredba

    Ulazni podaci, medurezultati i rezultati proracuna pohranjuju se u varijablama. Varijablecemo oznacavati s jednim ili vise kosih slova. Slicno kao u programskom jeziku Python,necemo deklarirati tip podataka koji spremamo u varijable.

    Spomenuli smo da algoritam uzima ulazne podatke i vraca izlazne podatke, koji pred-stavljaju rjesenje. Za ulaz i izlaz podataka u pseudojeziku koristimo naredbe ucitaj iispisi.

    Primjer 4.1. Program Hello world u pseudojeziku izgleda ovako:

    ispisi "Hello, world!"

    27

  • 28 POGLAVLJE 4. PSEUDOJEZIK

    Ovaj program doslovno ispisuje tekst u navodnicima. Ako iza naredbe ispisi stavimoime varijable (bez navodnika), nece se ispisati ime nego sadrzaj pohranjen u varijabli.Iza naredbe za ulaz podataka uvijek stoji ime jedne ili vise varijabli u koje ce se ucitanipodaci spremiti.

    Primjer 4.2. Program koji ucitava dva prirodna broja i ispisuje njihov zbroj:

    ucitaj m, nispisi m+ n

    Ovdje nismo raspisivali algoritam za zbrajanje prirodnih brojeva opisan u prvompoglavlju, nego smo samo napisali izraz m + n. Programski jezici sadrze gotovo rjesenjeza zbrajanje prirodnih brojeva, a isto cemo pretpostavljati za pseudojezik.

    Jedna od najvaznijih naredbi pseudojezika i pravih programskih jezika je naredba kojanekoj varijabli pridruzuje odredenu vrijednost. U primjerima algoritama iz prethodnihpoglavlja vec smo se susreli s pridruzivanjem. Oznacavali smo ga uglavnom znakomjednakosti =. Od sada cemo pridruzivanje uvijek oznacavati znakom , da bismo garazlikovali od usporedivanja.

    Na lijevoj strani naredbe za pridruzivanje stoji ime varijable. Na desnoj stranimoze biti konstanta, ime varijable ili izraz sastavljen od konstanti i varijabli s pomocuaritmetickih, logickih i znakovnih operacija. Izraz na desnoj strani se evaluira: imenavarijabli se zamjenjuju sa sadrzajem pohranjenim u tim varijablama i izracunavaju se sveoperacije. Konacna vrijednost se pohranjuje u varijablu napisanu s lijeva.

    Primjer 4.3.a 2b a+ 3c a bispisi c

    Prva naredba pohranjuje u varijablu a broj 2. Druga naredba pohranjuje u varijablu bvijednost spremljenu u a uvecanu za 3, tj. broj 5. Treca naredba pohranjuje u c produktvrijednosti spremljenih u a i b. Program na kraju ispisuje vrijednost spremljenu u c, tj. 10.

    Cesto je potrebno povecati vrijednost neke varijable. S time smo se vec susreli ualgoritmu iz dokaza teorema 2.2.

    Primjer 4.4.ucitaj xx x+ 1ispisi x

    Program ucitava broj u varijablu x, povecava vrijednost x za jedan i ispisuje novi x.Naprimjer, ako korisnik upise broj 17, program ce ispisati 18.

    Vidimo da izraz s desne strane naredbe za pridruzivanje moze sadrzati i varijablu kojusmo naveli na lijevoj strani. Naprimjer, naredba x 2x broj spremljen u x mnozi s 2 irezultat pohranjuje u x. S lijeve strane naredbe za pridruzivanje smije stajati iskljucivo

  • 29

    ime jedne varijable, nikada konstanta ili izraz. Pridruzivanja 2 x, x+1 x i x+y 2nemaju smisla. Osim brojeva, varijablama mozemo pridruzivati znakove, nizove znakova(stringove) i logicke vrijednosti.

    Primjer 4.5. Ovaj program takoder ispisuje poruku Hello, world!.

    poruka "Hello, world!"ispisi poruka

    Primjer 4.6. Program ispisuje ISTINA ako korisnik unese pozitivan broj, a u suprotnomispisuje LAZ.

    ucitaj brpoz br > 0ispisi poz

    Argumenti operatora usporedivanja >, 1)i = i+ 1

    nula x2 x 6 = 0a (x+ 2) i (y 7)b (x 0) + (y 0)

    Rjesenje. Prva naredba u varijablu uvjet sprema logicku vrijednost izraza (x < 1) ili(x > 1). Vrijednost je ISTINA ako je u varijabli x pohranjen broj koji je manji od 1 iliveci od 1, a u suprotnom je LAZ.

    U drugom retku naveden je logicki izraz, a ne naredba. Sam za sebe taj izraz nemasmisla. U sklopu neke naredbe izraz bi uvijek poprimio vrijednost LAZ, bez obzira nasadrzaj varijable i. Naime, i ne moze biti jednak i + 1. Ako zelimo povecati sadrzajvarijable i za 1, trebamo napisati naredbu za pridruzivanje i i+ 1.

    Treca naredba pohranjuje u varijablu nula logicku vrijednost ISTINA ili LAZ ovisnoo tome je li u x pohranjena nultocka polinoma x2 x 6 ili nije.

    Cetvrta i peta naredba nemaju smisla. Na desnoj strani cetvrte naredbe je logickaoperacija i primijenjena na aritmeticke izraze x+2 i y7, a u petoj naredbi je aritmetickaoperacija + primijenjena na logicke izraze x 0 i y 0. Napominjemo da se u nekimprogramskim jezicima (npr. C i Python) umjesto logickih vrijednosti ISTINA i LAZ koristebrojevi 1 i 0, pa bi tamo peta naredba imala smisla.

    Primjer 4.8. Napisite program koji ucitava neke vrijednosti u varijable x i y, zamjenjujesadrzaj tih varijabli i ispisuje ih.

  • 30 POGLAVLJE 4. PSEUDOJEZIK

    Rjesenje. Ako korisnik unese redom vrijednosti 5, 7, trazeni program treba ispisati 7, 5.Sljedeci program ponasa se identicno, ali ipak ne predstavlja rjesenje zadatka.

    ucitaj x, yispisi y, x

    Naime, u varijablama su i dalje pohranjene vrijednosti x = 5, y = 7. Niti ovaj programne radi ispravno:

    ucitaj x, yx yy xispisi x, y

    Nakon prvog pridruzivanja obje varijable sadrze broj 7, a broj 5 je izgubljen. Programce ispisati 7, 7. Rjesenje je da prije pridruzivanja x y broj koji je bio u x spremimo upomocnu varijablu. Na kraju cemo varijabli y pridruziti broj iz pomocne varijable.

    ucitaj x, ypom xx yy pomispisi x, y

    Zamjena varijabli cesta je i vazna operacija. Koristit cemo je npr. u algoritmima zasortiranje. Mozemo si je predociti preko problema zamjene dviju vrsti pica ulivenih upogresne case. Zamislimo da smo crno vino ulili u casu za bijelo vino, a bijelo u casu zacrno. Za zamijenu pica koristimo trecu, pomocnu casu (vidi sliku 4.1). Analogija ipaknije potpuna kad u casu B prelijemo pice iz case A, casa A ostane prazna. S drugestrane, nakon pridruzivanja b a obje varijable a, b sadrze vrijednost koja je bila u a.

    U dosadasnjim primjerima algoritama naredbe se izvode tocno onim redom kojimsu napisane. Cesto je potrebno utjecati na tijek izvodenja algoritma. U programskimjezicima i u pseudojeziku za to sluzi naredba za grananje, koja je oblika

    ako je logicki izraz onda[prvi niz naredbi

    inace[drugi niz naredbi

    Naredba za grananje evaluira logicki izraz. Ako je njegova vrijednost ISTINA, izvodise prvi niz naredbi, a u suprotnom se izvodi drugi niz naredbi. Cijeli drugi dio (inacei odgovarajuci niz naredbi) moze se izostaviti. Kljucne rijeci ako je . . . onda . . . inacena engleskom glase if . . . then . . . else, zato se naredba za grananje ponekad naziva ifnaredbom.

  • 31

    1. 2.

    3. 4.

    Slika 4.1: Zamjena pica ulivenih u pogresne case.

    Primjer 4.9. Program za rjesavanje kvadratne jednadzbe ax2 + bx+ c = 0.

    ucitaj a, b, cako je a 6= 0 onda

    d b2 4acako je d > 0 onda x1 (b+d)/(2a)x2 (bd)/(2a)

    ispisi "Rjesenja su ", x1, x2inace

    ako je d = 0 onda[x1 b/(2a)ispisi "Dvostruko rjesenje je ", x1

    inace[ispisi "Nema realnih rjesenja"

    inace

    ako je b 6= 0 onda[x c/bispisi "Rjesenje je ", x

    inaceako je c = 0 onda[

    ispisi "Svi realni brojevi su rjesenja"inace[

    ispisi "Nema rjesenja"

    Ovaj program predstavlja detaljni zapis u pseudojeziku nacina na koji izracunavamo

  • 32 POGLAVLJE 4. PSEUDOJEZIK

    formulu

    x1,2 =bb2 4ac

    2a.

    Raspisali smo sve moguce slucajeve (diskriminanta pozitivna, nula ili negativna, vodecikoeficijent nula).

    Jos jednu vaznu grupu naredbi koje utjecu na tijek izvodenja programa cine naredbeza ponavljanje, takozvane petlje (eng. loops). Pretpostavimo da zelimo ispisati prvih 100prirodnih brojeva. Bez naredbe za ponavljanje morali bismo napisati 100 naredbi za ispis:

    ispisi 1ispisi 2ispisi 3

    ...

    Elegantnije rjesenje sastoji se od petlje koja nekoj varijabli redom pridruzuje brojeve od1 do 100 i ispisuje vrijednost te varijable:

    za i = 1, . . . , 100 ponavljaj[ispisi i

    Ovaj oblik naredbe za ponavljanje naziva se for petljom, prema engleskom zapisu

    for i = 1, . . . , 100 do[...

    Varijabla koja poprima vrijednosti od 1 do 100 naziva se kontrolnom varijablom. Naravno,moguce je staviti neku drugu donju i gornju granicu za kontrolnu varijablu umjesto 1 i 100.Niz naredbi koje se ponavljaju zvat cemo tijelom petlje. U tijelu for petlje nije potrebnopovecavati vrijednost kontrolne varijable pretpostavljamo da se to dogada automatski.

    Postoji i drugi oblik naredbe za ponavljanje, takozvana while petlja:

    dok je logicki izraz ponavljaj[...

    ili, na engleskom:while logicki izraz do[

    ...

    Tijelo while petlje se ponavlja sve dok je logicki izraz istinit. Kad bismo s pomocu whilepetlje zeljeli ispisati brojeve od 1 do 100, morali bismo sami inicijalizirati i povecavatikontrolnu varijablu:

    i 1dok je i 100 ponavljaj[

    ispisi ii i+ 1

    Za neke probleme prakticnija je for petlja, a za druge while petlja.

  • 33

    Primjer 4.10. Napisite program koji ucitava prirodan broj n i ispisuje kvadrate prvih nprirodnih brojeva.

    Rjesenje. Ovaj zadatak lakse je rijesiti s for petljom, jer ne moramo brinuti o kontrolnojvarijabli:

    ucitaj nza i = 1, . . . , n ponavljaj[

    ispisi i2

    Primjer 4.11. Napisite program koji ucitava prirodan broj n i ispisuje prirodne brojeveiz skupa {1, . . . , n} koji su kvadrati nekog prirodnog broja.Rjesenje. Nespretno rjesenje bila bi for petlja s kontrolnom varijablom i = 1, . . . , n. Utijelu petlje provjeravali bismo je li i kvadrat prirodnog broja i ispisivali ga ako jest.

    Spretnije je umjesto i ispisivati i2, ali tada gornja granica za kontrolnu varijablu nije n.Petlja treba ici do najveceg prirodnog broja i za koji je i2 n. Taj uvjet mozemo napisatiu while petlji.

    ucitaj ni 1dok je i2 n ponavljaj[

    ispisi i2

    i i+ 1

    Primjer 4.12. Napisite program koji ucitava 100 brojeva i ispisuje njihov zbroj.

    Rjesenje. Koristimo pomocnu varijablu s kojoj na pocetku pridruzimo 0. Svaki puta kaducitamo broj x, pribrojimo ga pomocnoj varijabli: s s+x (pridruzimo varijabli s staruvrijednost od s uvecanu za x). Na kraju s sadrzi zbroj svih ucitanih brojeva.

    s 0za i = 1, . . . 100 ponavljaj[

    ucitaj xs s+ x

    ispisi s

    Primjer 4.13. Napisite program koji ucitava prirodne brojeve sve dok se ne ucita nula.Program treba ispisati produkt ucitanih prirodnih brojeva.

    Rjesenje. U ovom zadatku ne znamo unaprijed koliko ce se brojeva ucitati, pa se ko-ristimo while petljom. Produkt izracunavamo slicno kao sumu: pomocnu varijablu pinicijaliziramo na 1 i mnozimo je ucitanim brojevima.

    p 1ucitaj xdok je x 6= 0 ponavljaj[p p xucitaj x

    ispisi p

  • 34 POGLAVLJE 4. PSEUDOJEZIK

    Pretpostavimo da korisnik upise redom brojeve 2, 5, 3, 0. Primijetimo da se prvi brojucitava prije ulaza u petlju. Kada bi prvi ucitani broj bio 0, tijelo petlje uopce se ne biizvodilo, a program bi ispisao prazan produkt 1. U nasem slucaju program ce ucitatix = 2 i prvi puta izvesti tijelo petlje. Varijabli p se pridruzuje p x = 1 2 = 2 i ucitavase sljedeci broj, x = 5. Sada se ponovo provjerava uvjet x 6= 0, koji je istinit, i drugiputa izvodi tijelo petlje. Varijabli p se pridruzuje 2 5 = 10 i ucitava se x = 3. U trecemprolazu kroz petlju p postaje 30 i ucitava se 0. Sada uvjet x 6= 0 vise nije istinit, pa seizlazi iz petlje. Na kraju se ispisuje varijablu p, tj. produkt ucitanih brojeva 30.

    Primjer 4.14. Napisite program koji ucitava prirodan broj n i nakon toga n brojeva.Program treba ispisati koliko medu ucitanim brojevima ima negativnih.

    Rjesenje. U ovom primjeru pomocnu varijablu koristimo kao brojac. Na pocetku je inici-jaliziramo na 0 i povecavamo je za 1 svaki puta kad korisnik unese negativan broj.

    ucitaj nbr 0za i = 1, . . . , n ponavljaj ucitaj xako je x < 0 onda[

    br br + 1ispisi br

    Pokusajte sami detaljno opisati rad programa ako korisnik upise n = 5 i niz brojeva 2,1, 0, 7, 14.Primjer 4.15. Napisite program koji ucitava brojeve sve dok se ne ucita nula. Programtreba ispisati aritmeticku sredinu ucitanih brojeva (osim nule).

    Rjesenje. Aritmeticka sredina jednaka je sumi ucitanih brojeva podijeljenoj s brojemucitanih brojeva:

    A =x1 + x2 + . . .+ xn

    n.

    Koristit cemo dvije pomocne varijable prva prebrojava ucitane brojeve, a druga izracunavasumu.

    n 0s 0ucitaj xdok je x 6= 0 ponavljaj n n+ 1s s+ x

    ucitaj xako je n > 0 onda[

    ispisi s/ninace[

    ispisi "Nije ucitan niti jedan broj"

    Prije ispisa aritmeticke sredine provjeravamo je li ucitan barem jedan broj, da bismoizbjegli dijeljenje s nulom.

  • 35

    Primjer 4.16. Napisite program koji ucitava n brojeva i ispisuje najveci od ucitanihbrojeva.

    Rjesenje. U ovom programu koristit cemo pomocnu varijablu max u kojoj pamtimo naj-veci od do sada ucitanih brojeva. Ako je sljedeci ucitani broj veci od max, pridruzimo gavarijabli max:

    za i = 1 . . . , n ponavljaj ucitaj xako je x > max onda[max x

    Varijablu max moramo prije ulaza u petlju inicijalizirati. Ako znamo da ce korisnikupisati pozitivne brojeve, mozemo max postaviti na 0. Medutim, nije iskljuceno da cesvi upisani brojevi biti negativni. Tada bi program ispisao 0, sto nije najveci od ucitanihbrojeva. Rjesenje je da prvi broj ucitamo direktno u max, a nakon toga iducih n 1brojeva ucitavamo u petlji. Osim toga na pocetku programa treba ucitati n, a na krajuispisati max.

    ucitaj nucitaj maxza i = 1 . . . , n 1 ponavljaj ucitaj xako je x > max onda[

    max xispisi max

    Naredbe koje smo do sada upoznali dovoljne su za zapisivanje svih algoritama kojimacemo se baviti u ovoj skripti. Nasa verzija pseudojezika ima samo sest naredbi: ucitaj,ispisi, pridruzivanje , grananje (ako. . .onda. . .inace), for petlju i while petlju. Usestom poglavlju upoznat cemo se poblize s indeksiranim varijablama (nizovima, odnosnopoljima), koje smo vec susreli u uvodnim primjerima algoritma za zbrajanje i algoritmaiz dokaza teorema 2.2.

    U mnogim programskim jezicima osim opisanih naredbi postoji mogucnost definiranjafunkcija, odnosno potprograma (vidi primjere na kraju prethodnog poglavlja). Funkcije ipotprogrami potrebni su za elegantno zapisivanje rekurzivnih algoritama. Time se u ovojskripti necemo baviti, pa ne uvodimo u pseudojezik sintaksu za funkcije i potprograme.

    Zadaci

    Zadatak 4.1. Objasnite razliku izmedu pridruzivanja i usporedivanja =.

    Zadatak 4.2. Ako se na ulazu unesu brojevi a = 15 i b = 21, sto ce ispisati sljedeci

  • 36 POGLAVLJE 4. PSEUDOJEZIK

    program?ucitaj a, ba a bb 2 a+ 1a 3 b 7ispisi a b

    Zadatak 4.3. Istrazite sto radi sljedeci program.

    ucitaj x, yx x yy x+ yx y xispisi x, y

    Zadatak 4.4. Nadopunite program za rjesavanje kvadratne jednadzbe (primjer 4.9) takoda ispisuje kompleksna rjesenja ako je diskriminanta negativna.

    Zadatak 4.5. Napisite program za rjesavanje sustava od dvije linearne jednadzbe s dvijenepoznanice

    a x+ b y = ec x+ d y = f

    .

    Program treba raditi ispravno u svim mogucim slucajevima (jedinstveno rjesenje, beskonacnomnogo rjesenja, bez rjesenja).

    Zadatak 4.6. Za zadani n, napisite formulu za najveci prirodan broj i za koji je i2 n.Rijesite zadatak iz primjera 4.11 s pomocu for petlje.

    Zadatak 4.7. Napisite program koji ucitava prirodan broj n i ispisuje prvih n parnihprirodnih brojeva.

    Zadatak 4.8. Napisite program koji ucitava prirodan broj n i ispisuje prvih n prirodnihbrojeva koji pri dijeljenju s 3 daju ostatak 1.

    Zadatak 4.9. Napisite program koji ucitava prirodan broj n i ispisuje sve brojeve iz skupa{1, 2, . . . , n} koji su djeljivi s 5.Zadatak 4.10. Napisite program koji ucitava prirodan broj n i ispisuje sve brojeve izskupa {1, 2, . . . , n} koji su parni, ali nisu djeljivi s 4.Zadatak 4.11. Napisite program koji ucitava n prirodnih brojeva i ispisuje sumu svihucitanih brojeva koji su parni.

    Zadatak 4.12. Napisite program koji ucitava brojeve sve dok se ne ucita nula. Programtreba ispisati produkt svih negativnih ucitanih brojeva.

    Zadatak 4.13. Napisite program koji ucitava cijele brojeve sve dok se ne ucita nula.Program treba ispisati koliko medu ucitanim brojevima ima neparnih.

  • 37

    Zadatak 4.14. Napisite program koji ucitava brojeve sve dok se ne ucita nula. Programtreba ispisati geometrijsku sredinu ucitanih brojeva (osim nule):

    G = nx1 x2 xn.

    Zadatak 4.15. Rijesite prethodni zadatak za kvadratnu sredinu

    K =

    x21 + x

    22 + . . .+ x

    2n

    n

    i harmonijsku sredinu

    H =n

    1x1

    + 1x2

    + . . .+ 1xn

    .

    Zadatak 4.16. Napisite program koji ucitava brojeve sve dok se ne ucita nula. Programtreba ispisati najmanji pozitivan broj od ucitanih. Ako nije ucitan niti jedan pozitivanbroj, program treba ispisati poruku o tome.

    Zadatak 4.17. Napisite program koji ucitava cijele brojeve sve dok se ne ucita nula.Program treba ispisati najveci neparni ucitani broj. Ako nije ucitan niti jedan neparnibroj, program treba ispisati poruku o tome.

    Zadatak 4.18. Niz Fibonaccijevih brojeva definiran je rekurzivno. Prva dva clana nizasu F1 = F2 = 1, a svaki sljedeci je zbroj dva prethodna: Fn = Fn1 + Fn2, za n 2.Napisite program koji ucitava n i ispisuje prvih n clanova tog niza.

    Zadatak 4.19. Napisite program koji ucitava prirodan broj n i ispisuje sve Fibonaccijevebrojeve iz skupa {1, . . . , n}.Zadatak 4.20. Napisite program koji ucitava prirodan broj n i ispisuje n-ti Fibonaccijevbroj Fn.

    Zadatak 4.21. Napisite program koji ucitava prirodan broj n i ispisuje najveci Fibo-naccijev broj koji je manji ili jednak od n.

    Zadatak 4.22. Napisite program koji ucitava prirodan broj n i ispisuje najmanji Fibo-naccijev broj koji je veci ili jednak od n.

  • 38 POGLAVLJE 4. PSEUDOJEZIK

  • Poglavlje 5

    Neki algoritmi za prirodne brojeve

    U ovom poglavlju upoznat cemo neke algoritme koji rade s prirodnim brojevima. Pocinjemos problemima o znamenkama zadanog prirodnog broja. Ako zelimo ispisati znamenkejednu po jednu, koristimo algoritam koji smo upoznali u drugom poglavlju:

    ucitaj ndok je n 6= 0 ponavljaj[

    ispisi n mod 10n n div 10

    Ovaj algoritam ispisuje dekadske znamenke, ali ga jednostavno mozemo modificirati takoda radi s bilo kojom bazom b. Primijetimo da se znamenke ispisuju s desna na lijevo, tj.od namanje znacajne prema znacajnijima (prvo znamenka jedinice, zatim desetice, stoticeitd.). Koristili smo while petlju jer ne znamo unaprijed koliko ce biti znamenaka.

    Osnovnu petlju po znamenkama zadanog prirodnog broja sad cemo koristiti za prob-leme kakve smo imali u prethodnom poglavlju prebrojavanje, izracunavanje sume,trazenje maksimuma. . .

    Primjer 5.1. Napisite program koji ucitava prirodan broj n i ispisuje koliko n ima zna-menaka.

    Rjesenje. Modificiramo prethodni algoritam tako da se umjesto ispisivanja znamenakapovecava brojac.

    ucitaj nbr 0dok je n 6= 0 ponavljaj[br br + 1n n div 10

    ispisi br

    Ako smijemo koristiti logaritamsku funkciju i funkciju najvece cijelo, problem mozemorijesiti bez petlje.

    ucitaj nispisi blog nc+ 1

    39

  • 40 POGLAVLJE 5. NEKI ALGORITMI ZA PRIRODNE BROJEVE

    Primjer 5.2. Napisite program koji ucitava prirodan broj n i ispisuje sumu njegovihznamenaka.

    Rjesenje.ucitaj ns 0dok je n 6= 0 ponavljaj[s s+ (n mod 10)n n div 10

    ispisi s

    Primjer 5.3. Napisite program koji ucitava prirodan broj n i ispisuje njegovu najvecuznamenku.

    Rjesenje.ucitaj nmax 0dok je n 6= 0 ponavljaj z n mod 10ako je z > max onda max zn n div 10

    ispisi max

    Primjer 5.4. Napisite program koji ucitava prirodan broj n i definira prirodan broj m kojise sastoji od istih znamenaka kao n, ali u obrnutom redoslijedu. Naprimjer, ako korisnikunese n = 123, program treba ispisati m = 321.

    Rjesenje.ucitaj nm 0dok je n 6= 0 ponavljaj z n mod 10m m 10 + zn n div 10

    ispisi m

    Iduca grupa algoritama radi s djeliteljima zadanog prirodnog broja. Ako zelimo ispisatisve djelitelje od n, najprirodnije rjesenje je for petlja od 1 do n:

    ucitaj nza d = 1, . . . , n ponavljaj[

    ako je n mod d = 0 onda ispisi d

    Broj d je djelitelj od n ako je ostatak pri dijeljenju n sa d jednak nuli, tj. ako vri-jedi n mod d = 0. Slijedi nekoliko primjera koji se rjesavaju s pomocu petlje po svimdjeliteljima.

  • 41

    Primjer 5.5. Napisite program koji ucitava prirodan broj n i ispisuje koliko n imadjelitelja.

    Rjesenje.ucitaj nbr 0za d = 1, . . . , n ponavljaj[

    ako je n mod d = 0 onda br br + 1ispisi br

    Primjer 5.6. Napisite program koji ucitava prirodan broj n i ispisuje sumu svih djeliteljaod n.

    Rjesenje.ucitaj ns 0za d = 1, . . . , n ponavljaj[

    ako je n mod d = 0 onda s s+ dispisi s

    Primjer 5.7. Napisite program koji ucitava prirodan broj n i ispisuje njegov najmanjidjelitelj veci od 1 i najveci djelitelj manji od n.

    Rjesenje. Najmanji djelitelj svakog prirodnog broja je 1, a najveci on sam. Zato smo tadva djelitelja iskljucili iz razmatranja. Za ovaj problem dat cemo elegantnije rjesenje odfor petlje po svim djeliteljima s pomocnim varijablama min i max. Takva petlja pronalazidjelitelje redom od manjih prema vecima. Prvi kojeg pronade nakon 1 je trazeni najmanjidjeljitelj, pa mozemo odmah izaci iz petlje i ispisati ga.

    ucitaj nd 2dok je n mod d 6= 0 ponavljaj d d+ 1ispisi d

    Primijetimo da je najmanji djelitelj d uvijek prost broj. U suprotnom bismo d moglinapisati kao d = a b za neke a, b < d, pa bi a i b bili jos manji djelitelji od n. Za najvecidjelitelj koristimo silaznu petlju:

    ucitaj nd n 1dok je n mod d 6= 0 ponavljaj d d 1ispisi d

    Program mozemo uciniti efikasnijim tako da petlja krece od n div 2 umjesto od n 1:ucitaj nd n div 2dok je n mod d 6= 0 ponavljaj d d 1ispisi d

  • 42 POGLAVLJE 5. NEKI ALGORITMI ZA PRIRODNE BROJEVE

    Naime, niti jedan broj izmedu n div 2 i n ne moze biti djelitelj od n. Ako zelimo ispisatinajmanji i najveci djelitelj, ne moramo imati obje petlje (uzlaznu i silaznu). Najvecidjeljitelj ocito je jednak broju n podijeljenim s najmanjim djeliteljem.

    ucitaj nd 2dok je n mod d 6= 0 ponavljaj d d+ 1ispisi dispisi n div d

    Primjer 5.8. Napisite program koji ucitava prirodne brojeve m i n te ispisuje sve njihovezajednicke djelitelje.

    Rjesenje.ucitaj m,nza d = 1, . . . ,m ponavljaj[

    ako je (m mod d = 0) i (n mod d = 0) onda ispisi d

    Primjer 5.9. Napisite program koji ucitava prirodne brojeve m i n te ispisuje njihovnajveci zajednicki djelitelj.

    Rjesenje.

    ucitaj m,nd mdok je (m mod d 6= 0) ili (n mod d 6= 0) ponavljaj d d 1ispisi d

    Prethodni primjer rjesili smo slicno kao primjer 5.7. Ponudeno rjesenje je vrlo jednos-tavno; korektnost slijedi direktno iz definicije najveceg zajednickog djelitelja. Za problemnajveceg zajednickog djelitelja postoji manje trivijalan, ali efikasniji i ljepsi algoritam. Toje poznati Euklidov algoritam:

    ucitaj m,ndok je n 6= 0 ponavljaj pom nn m mod nm pom

    ispisi m

    Algoritam ucitava prirodne brojeve m i n. Pretpostavljamo da je prvi broj veci ili jednakod drugog, m n. Petlja se izvodi dok je manji broj razlicit od nule. U tijelu petljevarijabli n se pridruzuje ostatak pri dijeljenju m sa n, a varijabli m stara vrijednost od n.Primijetimo da je prethodno stara vrijednost od n pohranjena u pomocnu varijablu pom,slicno kao kod zamjene varijabli. Kad varijabla n postane nula, algoritam izlazi iz petljei ispisuje m.

  • 43

    Primjer 5.10. Opisimo rad Euklidova algoritma za ulaz m = 30, n = 21. U prvomprolazu kroz petlju u varijablu pom se pohranjuje 21, varijabla n postaje 30 mod 21 = 9,a u m se prepisuje broj pohranjen u pom. Vrijednosti varijabli su tada m = 21, n = 9.Buduci da n nije nula, drugi puta se izvodi tijelo petlje. Vrijednosti varijabli postajum = 9, n = 21 mod 9 = 3. U trecem prolazu kroz petlju varijable postaju m = 3,n = 9 mod 3 = 0. Tada algoritam izlazi iz petlje i ispisuje m = 3, sto je najveci zajednickidjelitelj od 30 i 21.

    Korektnost Euklidova algoritma nije ocita. Trebamo se uvjeriti da algoritam zavrsavau konacno mnogo koraka za bilo koje brojeve m, n na ulazu te da je broj kojeg ispisuje nakraju zaista najveci zajednicki djelitelj od m i n. Konacnost slijedi iz teorema o dijeljenjus ostatkom (teorem 2.3). U svakom koraku zamjenjujemo n s ostatkom pri dijeljenju m san, koji je strogo manji od n. Dobivamo strogo padajuci niz nenegativnih cijelih brojeva,koji ima konacno mnogo clanova prije nego sto dode do nule. Tada algoritam izlazi izpetlje, ispisuje m i zavrsava s radom.

    Najveci zajednicki djelitelj oznacavat cemo NZM(m,n) (prema najveca zajednickamjera). Ako je m djeljiv s n, ocito je NZM(m,n) = n. Ako m nije djeljiv s n, mozese pokazati da vrijedi NZM(m,n) = NZM(n,m mod n). Iz toga slijedi da je broj kojegEuklidov algoritam ispisuje upravo NZM(m,n). Algoritam unutar petlje zamjenjuje mi n redom s n i m mod n. Pritom se ne mijenja najveci zajednicki djelitelj brojevapohranjenih u varijablama m i n. U zadnjem prolazu kroz petlju n postaje nula, a toznaci da je prethodno m bio djeljiv s n. Ispisuje se vrijednost varijable m u zadnjemkoraku, koja je jednaka vrijednosti n u prethodnom koraku. Tada je m bio djeljiv s n, paje vrijedilo n = NZM(m,n). Dakle, Euklidov algoritam ispisuje NZM(m,n).

    Najveci zajednicki djelitelj naziva se i najvecom zajednickom mjerom, a Euklidovalgoritam duboko je povezan s problemom mjerenja. Pretpostavimo da su zadane dvijeduzine duljina a i b. Brojevi a i b su pozitivni realni brojevi za koje pretpostavljamoa > b, tj. da je prva duzina veca od druge. Izmjeriti prvu duzinu drugom znaci ispitatikoliko puta druga duzina stane u prvu:

    a

    b

    b b b o

    Slika 5.1: Mjerenje duzine a duzinom b.

    Ako a nije cjelobrojni visekratnik od b, ostat ce nam dio kraci od b (ostatak).Postupak mozemo opisati sljedecim algoritmom, koji uzastopno oduzima b od a dok a ne

  • 44 POGLAVLJE 5. NEKI ALGORITMI ZA PRIRODNE BROJEVE

    postane manji od b.

    ucitaj a, bk 0dok je a b ponavljaj[a a bk k + 1

    ispisi k, a

    Algoritam ispisuje cijeli broj k, koji nam kaze koliko puta b stane u a, i duljinu ostatka.To je zapravo dokaz tvrdnje o egzistenciji iz sljedece generalizacije teorema o dijeljenju sostatkom.

    Teorem 5.11. Neka su a, b > 0 pozitivni realni brojevi. Tada postoje jedinstveni brojevik N0 i o R, 0 o < b takvi da je a = k b+ o.

    Problem mjerenja sastoji se u pronalazenju zajednicke mjere kojom mozemo izmje-riti obje duzine bez ostatka. To je duzina duljine d takve da su a i b njezini cjelobrojnivisekratnici: a = m d i b = n d za neke m,n N. Tada je razlomak m

    nodgovor na

    pitanje koliko puta b stane u a. Sto je zajednicka mjera d veca, to su brojnik i nazivnikmanji i mjerenje nam je prakticnije. Zato trazimo najvecu zajednicku mjeru.

    a

    b

    d

    Slika 5.2: Zajednicka mjera d duzina a i b.

    Euklidov algoritam je pokusaj da se problem mjerenja sustavno rijesi. U prvom korakumjerimo vecu duzinu a manjom duzinom b. Ako ostatak o1 nije nula, nastavljamo mjeritimanju duzinu b s ostatkom o1. Ako ni u drugom koraku ostatak o2 nije nula, mjerimoo1 s ostatkom o2 i tako dalje. Kada dobijemo ostatak nula, sve promatrane velicine sucjelobrojni visekratnici zadnjeg pozitivnog ostatka. Tako nalazimo najvecu zajednickumjeru duzina a i b.

    Vidjeli smo da se jedno mjerenje svodi na uzastopno oduzimanje manje duzine odvece. Prosirenje tog postupka daje nam drugu verziju Euklidova algoritma. Oduzimamob od a dok a ne postane manji od b. Tada nastavljamo oduzimati a od b, i tako dalje svedok se a i b ne izjednace.

  • 45

    ucitaj a, bdok je a 6= b ponavljaj[

    ako je a > b onda a a binace b b a

    ispisi a

    Ova verzija Euklidova algoritma zasniva se na oduzimanju. Za prirodne brojevea, b N ispisuje isti rezultat kao prva verzija Euklidova algoritma, u kojoj smo racunaliostatke pri dijeljenju. Algoritam s oduzimanjem obicno treba vise koraka od prve verzijealgoritma, ali ga mozemo primijeniti na pozitivne realne brojeve, a ne samo na prirodnebrojeve.

    Postavlja se pitanje hoce li algoritam zavrsiti u konacno mnogo koraka za bilo kojerealne brojeve a, b > 0 na ulazu? Ako algoritam pronade najvecu zajednicku mjeru d,onda je a

    b= md

    nd =mn

    racionalan broj. Prema tome, ako je omjer brojeva na ulazuiracionalan, algoritam ne zavrsava.

    Definicija 5.12. Za realne brojeve a, b 6= 0 kazemo da su sumjerljivi ako je njihov omjerab

    racionalan broj. U suprotnom kazemo da su nesumjerljivi.

    Starogrcki matematicari bili su zapanjeni otkricem nesumjerljivih velicina, naprimjerstranice i dijagonale kvadrata. Za takve duzine ne postoji zajednicka mjera, a Euklidovalgoritam izvodio bi se beskonacno. Naravno, svako mjerenje u stvarnom zivotu nuznoukljucuje pogresku i kao rezultat daje aproksimaciju. Medutim, ovo pokazuje da cak niidealizirano mjerenje ne moze biti egzaktno.

    Vratimo se algoritmima za prirodne brojeve. U sljedecim primjerima koristimo seEuklidovim algoritmom.

    Primjer 5.13. Napisite program koji ucitava dva prirodna broja i ispisuje poruku o tomejesu li relativno prosti.

    Rjesenje. Brojevi su relativno prosti ako je njihov najveci zajednicki djelitelj 1. Izracunavamoga Euklidovim algoritmom i usporedujemo s 1:

    ucitaj m,ndok je n 6= 0 ponavljaj pom nn m mod nm pom

    ako je m = 1 onda[ispisi "Brojevi su relativno prosti"

    inace[ispisi "Brojevi nisu relativno prosti"

    Primjer 5.14. Napisite program koji ucitava brojnik i nazivnik razlomka i ispisuje ga udo kraja skracenom obliku.

  • 46 POGLAVLJE 5. NEKI ALGORITMI ZA PRIRODNE BROJEVE

    Rjesenje. Trebamo podijeliti brojnik i nazivnik njihovom najvecom zajednickom mjerom.Buduci da Euklidov algoritam mijenja vrijednosti varijabli m i n, pohranit cemo pocetnevrijednosti u pomocne varijable.

    ucitaj m,na mb ndok je n 6= 0 ponavljaj pom nn m mod nm pom

    ispisi a div m, " / ", b div m

    Primjer 5.15. Napisite program koji ucitava dva prirodna broja i ispisuje njihov najmanjizajednicki visekratnik.

    Rjesenje. Najmanji zajednicki visekratnik dobijemo tako da pomnozimo brojeve i podi-jelimo produkt s najvecim zajednickim djeliteljem.

    ucitaj m,np m ndok je n 6= 0 ponavljaj pom nn m mod nm pom

    ispisi p div m

    Vazan matematicki pojam je pojam prostog broja. Za prirodan broj n > 1 kazemoda je prost ako su mu jedini djelitelji 1 i n. Mozemo reci da je n prost ako ima tocno dvadjelitelja. Brojeve s vise od dva djelitelja nazivamo slozenim, a broj 1 nije niti prost nitislozen. Sljedeci algoritam ucitava n i provjerava je li prost.

    ucitaj nbr 0za d = 1, . . . , n ponavljaj[

    ako je n mod d = 0 onda br br + 1ako je br = 2 onda[

    ispisi "Broj je prost"inace[

    ispisi "Broj nije prost"

    Algoritam prebrojava djelitelje od n. Ako ima tocno dva djelitelja onda je prost, a usuprotnom je n = 1 ili je n slozen broj. Cim nademo prvi djelitelj izmedu 1 i n, znamo daje rijec o slozenom broju. Ovaj algoritam napisan je s for petljom i nastavlja prebrojavati

  • 47

    djelitelje. S while petljom mozemo napisati efikasniji algoritam, koji ce prekinuti potragukad nade prvi djelitelj. U primjeru 5.7 vec smo spomenuli da brojevi izmedu (n div 2) in ne mogu biti djelitelji, pa ih ne moramo provjeravati.

    ucitaj nako je n = 1 onda[

    ispisi "Broj nije ni prost ni slozen"inaced 2dok je (n mod d 6= 0) i (d n div 2) ponavljaj d d+ 1ako je d n div 2 onda[

    ispisi "Broj je slozen"inace[

    ispisi "Broj je prost"

    Algoritam mozemo uciniti jos efikasnijim tako da potragu za djeliteljima ogranicimo don. Naime, moze se pokazati da najmanji djelitelj izmedu 1 i n ne moze biti veci od

    n

    (ako postoji).

    ucitaj nako je n = 1 onda[

    ispisi "Broj nije ni prost ni slozen"inaced 2dok je (n mod d 6= 0) i (d2 n) ponavljaj d d+ 1ako je d2 n onda[

    ispisi "Broj je slozen"inace[

    ispisi "Broj je prost"

    Primjer 5.16. Ako korisnik unese n = 17, prebrojimo za koliko brojeva d prethodnatri algoritma provjeravaju jesu li djelitelji od n. Prvi algoritam provjerava sve brojeveod 1 do n, dakle napravi ukupno 17 provjera. Drugi algoritam trazi djelitelje od 2 do17 div 2 = 8, dakle napravi 7 provjera. Treci algoritam provjerava brojeve d 2 kojizadovoljavaju d2 17, tj. brojeve od 2 do 4. Nakon samo tri provjere ispravno zakljucujeda je 17 prost broj.

    Prema osnovnom teoremu aritmetike, svaki prirodan broj moze se prikazati kao pro-dukt prostih brojeva. Prikaz je jedinstven do na poredak faktora. Nije tesko napisatialgoritam koji ucitava prirodan broj n i ispisuje njegove proste faktore. Koristit cemoprimjedbu iz primjera 5.7 prema kojoj je najmanji djelitelj veci od 1 nuzno prost. Dokje n > 1, ispisivat cemo najmanji djelitelj d i podijeliti n sa d. Tako dobivamo prostefaktore od n u rastucem redoslijedu. Pritom ne moramo provjeravati jesu li brojevi koje

  • 48 POGLAVLJE 5. NEKI ALGORITMI ZA PRIRODNE BROJEVE

    ispisujemo prosti.ucitaj nd 2dok je n > 1 ponavljaj

    dok je n mod d = 0 ponavljaj[ispisi dn n div d

    d d+ 1Primjer 5.17. Opisimo kako prethodni algoritam nalazi proste faktore broja n = 84. Priulazu u vanjsku petlju vrijednosti varijabli su n = 84, d = 2. Unutarnja petlja se izvodidok je n mod d = 0, sto je ispunjeno. Pri prvom prolazu kroz unutarnju petlju ispisuje se2 i n postaje 42. Uvjet n mod d = 0 i dalje je ispunjen, pa algoritam jos jednom prolazikroz unutarnju petlju. Ponovo ispisuje 2 i postavlja n na 21. Taj broj vise nije djeljiv s 2,pa algoritam izlazi iz unutarnje petlje i povecava d za jedan. Nakon prvog prolaza krozvanjsku petlju vrijednosti varijabli su n = 21, d = 3.

    Buduci da je n > 1, algoritam drugi puta ulazi u vanjsku petlju. Unutarnja petljaispisuje 3 i postavlja n na 7. Po izlazu iz unutarnje petlje povecava se d, pa su vrijednostivarijabi n = 7, d = 4.

    Nakon drugog prolaza kroz vanjsku petlju algoritam povecava d od 4 do 6. Broj n = 7nije djeljiv s tim brojevima, pa algoritam ne ulazi u unutarnju petlju. U sestom prolazukroz vanjsku petlju d je 7, unutarnja petlja ispisuje 7 i postavlja n na 1, a zatim se d povecana 8. Algoritam izlazi iz vanjske petlje i zavrsava s radom. Ispisao je redom brojeve 2, 2,3, 7, a to su prosti faktori od 84.

    U ovom poglavlju nastojali smo razviti efikasne algoritme, koji zavrsavaju s radom usto manje koraka. Buduci da moderna racunala izvode operacije fantasticnim brzinama,postavlja se pitanje je li to uopce bitno? Pretpostavimo da se u jednoj sekundi izvodimilijardu (109) koraka algoritma. To je usporedivo s mogucnostima danasnjih procesora,iako se u stvarnosti svi koraci ne izvode jednakom brzinom. Razmotrit cemo koliko vre-mena treba za tri karakteristicna problema: izracunavanje najveceg zajednickog djelitelja,provjera je li broj prost i rastavljanje na proste faktore. Na ulazu cemo pretpostavljativelike prirodne brojeve s oko 50 znamenaka, tj. reda velicine 1050.

    U primjeru 5.9 dali smo prvi algoritam za najveci zajednicki djelitelj. Ako na ulazuimamo relativno proste brojeve reda velicine 1050, algoritam smanjuje varijablu d od 1050

    do 1 i tek tada ispisuje najveci zajednicki djelitelj 1. Dakle, treba mu oko 1050 koraka.To znaci da bi izvodenje algoritma trajalo oko 1041 sekundi, tj. oko 3.2 1033 godina. Zausporedbu, starost svemira procjenjuje se na 1.4 1010 godina (prema [26]).

    Brojevi s 50 znamenaka ipak nisu izvan dosega danasnjih racunala. Euklidov algoritamvrlo brzo nalazi najveci zajednicki djelitelj cak i tako velikih brojeva. Netrivijalan je, alidugo poznat rezultat [16] da Euklidovom algoritmu treba najvise koraka ako su na ulazuuzastopni Fibonaccijevi brojevi. Tocnije, najmanji brojevi za koje Euklidov algoritam nputa prolazi kroz petlju su Fn+2 i Fn+1. Prva dva Fibonaccijeva broja veca od 10

    50 suF241 i F242. Euklidov algoritam izracunava njihov najveci zajednicki djelitelj nakon 240prolaza kroz petlju. Ako jedan prolaz brojimo kao tri koraka (zbog tri pridruzivanja unutarpetlje), algoritam zavrsava za 7.2 107 sekundi, tj. u vremenu kracem od mikrosekunde

  • 49

    (milijuntog dijela sekunde). U stvarnosti za operacije s tako velikim brojevima treba visevremena nego sto smo pretpostavili, ali cijeli racun zaista zavrsava u djelicu sekunde.

    Za algoritam koji provjerava je li prirodan broj prost, najgori slucaj je kad zadamoprost broj. Prva verzija algoritma na str. 46 provjerava sve brojeve iz skupa {1, . . . , n}.Dakle, za broj s 50 znamenaka treba oko 1050 koraka i vrijeme izvodenja je 3.2 1033godina. Efikasnija verzija algoritma na str. 47 provjerava brojeve do

    n. Za prost broj s

    50 znamenaka treba oko 1025 koraka, ili 3.2 108 godina. To je krace od starosti svemira,ali je takoder duze nego sto bismo zeljeli cekati.

    Postoje efikasni algoritmi za provjeru prostosti, koji brojeve s 50 znamenaka rjesavajubrzo. Prvi takav algoritam u smislu kojeg koristimo u ovoj skripti opisan je 2004. godineu clanku [1]. Od ranije su poznati randomizirani algoritmi i algoritmi kojima korektnostovisi o nedokazanim hipotezama o prostim brojevima (vidi [29]). Ti su algoritmi relativnokomplicirani i necemo se njima baviti.

    Za problem rastavljanja zadanog prirodnog broja na proste faktore do danas nijepoznat niti jedan efikasan algoritam. Nas algoritam na str. 48 za prost broj reda velicine1050 treba vrijeme dulje od starosti svemira. Poznati su znatno efikasniji algoritmi, aliniti jedan na danasnjim racunalima ne moze brzo faktorizirati brojeve s 200 znamenaka.Opcenito, najgori slucaj za faktorizaciju su brojevi koji su produkt dvaju velikih prostihbrojeva.

    Racunski problemi s velikim prirodnim brojevima nisu samo od teorijskog znacaja.Neki od kriptografskih algoritama koji se koriste u praksi za bankovne transakcije puteminterneta i drugo zasnivaju se upravo na problemima koje smo razmatrali. Oni ne bi bilimoguci da ne mozemo brzo racunati najvecu zajednicku mjeru i provjeravati prostost, asigurnost im se zasniva na nemogucnosti faktorizacije velikih prirodnih brojeva.

    U sljedecem poglavlju opisat cemo kako se procjenjuje efikasnost algoritama bez racu-nanja vremena izvodenja za konkretne ulazne vrijednosti.

    Zadaci

    Zadatak 5.1. Napisite program koji ucitava prirodne brojeve n i b 2 te ispisuje zna-menke broja n u bazi b.

    Zadatak 5.2. Napisite program koji ucitava prirodne brojeve n i b 2 te ispisuje arit-meticku sredinu znamenaka broja n u bazi b.

    Zadatak 5.3. Napisite program koji ucitava prirodne brojeve n i b 2 te ispisuje kolikoznamenaka razlicitih od nule ima u zapisu broja n u bazi b.

    Zadatak 5.4. Napisite program koji ucitava prirodan broj n i ispisuje bazu b u kojoj nima najvise znamenaka razlicitih od nule.

    Zadatak 5.5. Napisite program koji ucitava prirodne brojeve n i b 2 te ispisuje zna-menke broja n u bazi b s lijeva na desno, tj. od najznacajnije prema manje znacajnima.

    Zadatak 5.6. Napisite program koji ucitava prirodan broj n i ispisuje produkt svih djeliteljaod n.

  • 50 POGLAVLJE 5. NEKI ALGORITMI ZA PRIRODNE BROJEVE

    Zadatak 5.7. Napisite program koji ucitava prirodan broj n i ispisuje aritmeticku sredinusvih djelitelja od n.

    Zadatak 5.8. Dokazite: za svaki prirodan broj n, najmanji broj d > 1 koji dijeli n jeprost.

    Zadatak 5.9. Dokazite: za svaki prirodan broj n, brojevi izmedu (n div 2) i n nisudjelitelji od n.

    Zadatak 5.10. Istrazite sto ce se dogoditi ako u Euklidov algoritam na str. 42 upisemobrojeve m < n.

    Zadatak 5.11. Dokazite: ako je prirodan broj n djelitelj od m, onda vrijedi NZM(m,n) =n.

    Zadatak 5.12. Dokazite: ako prirodan broj n nije djelitelj od m, onda vrijedi NZM(m,n) =NZM(n,m mod n).

    Zadatak 5.13. Dokazite teorem 5.11.

    Zadatak 5.14. Opisite rad verzije Euklidova algoritma s oduzimanjem (na str. 45) zaulaz m = 30, n = 21. Koliko prolaza kroz petlju treba tom algoritmu, a koliko Euklidovualgoritmu na str. 42?

    Zadatak 5.15. Dokazite da su duljina stranice i duljina dijagonale kvadrata nesumjerljivibrojevi.

    Zadatak 5.16. Napisite program koji ucitava dva razlomka i ispisuje njihov produkt u dokraja skracenom obliku.

    Zadatak 5.17. Napisite program koji ucitava dva razlomka i ispisuje njihov zbroj u dokraja skracenom obliku.

    Zadatak 5.18. Neka je NZM(m,n) najveci zajednicki djelitelj, a NZV(m,n) najmanjizajednicki visekratnik brojeva m i n. Dokazite da za sve prirodne brojeve m, n vrijediNZM(m,n) NZV(m,n) = m n.Zadatak 5.19. Napisite program koji ucitava prirodne brojeve sve dok se ne ucita nula.Program treba ispisati najveci zajednicki djelitelj svih ucitanih brojeva (osim nule).

    Zadatak 5.20. Eulerova funkcija (n) definira se kao broj prirodnih brojeva k n kojisu relativno prosti s n. Napisite program koji ucitava prirodan broj n i ispisuje (n).

    Zadatak 5.21. Neka je n slozen broj. Ako je d njegov najmanji djelitelj veci od 1, dokaziteda je d n.Zadatak 5.22. Napisite program koji ucitava prirodan broj n i ispisuje sve proste brojeveiz skupa {1, . . . , n}.Zadatak 5.23. Napisite program koji ucitava prirodan broj n i ispisuje prvih n prostihbrojeva.

  • 51

    Zadatak 5.24. Napisite program koji ucitava prirodan broj n i ispisuje n-ti po redu prostbroj.

    Zadatak 5.25. Napisite program koji ucitava prirodan broj n i ispisuje najmanji prostbroj p n.Zadatak 5.26. Napisite program koji ucitava prirodan broj n 2 i ispisuje najveci prostbroj p n.Zadatak 5.27. Prisjetite se algoritma za racunanje najveceg zajednickog djelitelja iz os-novne skole: brojeve m i n rastavimo na proste faktore, trazimo zajednicke proste faktorei pomnozimo ih. Pokusajte precizno zapisati taj algoritam! Bi li taj algoritam bio efikasanza velike prirodne brojeve m i n?

  • 52 POGLAVLJE 5. NEKI ALGORITMI ZA PRIRODNE BROJEVE

  • Poglavlje 6

    Nizovi i sortiranje

    Nizovi ili polja (eng. arrays) su indeksirane varijable. Cesto je u algoritmu potrebnopamtiti veci broj podataka, koji moze ovisiti o instanci problema kojeg rjesavamo. Tadaih nije prakticno pohraniti u varijable fiksnih imena a, b, c, . . ., nego ih pohranjujemou niz varijabli a1, a2, . . . , an. Duljina niza n takoder moze biti varijabla.

    U uvodnom poglavlju vec smo se susreli s nizovima varijabli. Algoritam za zbrajanjeprirodnih brojeva kao ulaz je uzimao dva niza znamenaka pribrojnika, a izlaz je bio nizznamenaka zbroja. Oznacavali smo ih a1, . . . , an, b1, . . . , bn i c1, . . . , cn+1. Ubuduce cemoindekse nizova pisati u uglatim zagradama: a[1], . . . , a[n], b[1], . . . , b[n] i c[1], . . . , c[n+ 1].Takva notacija koristi se u mnogim programskim jezicima (vidi primjere na str. 24).

    U klasicnim programskim jezicima kao sto su FORTRAN, Pascal i C potrebno jedeklarirati tip podataka koji se spremaju u niz (npr. cijeli brojevi, realni brojevi iliznakovi) i maksimalnu duljinu niza. Racunalo rezervira odgovarajucu kolicinu memo-rije za pohranjivanje podataka u nizu, obicno na uzastopnim memorijskim lokacijama. UPythonu je interna reprezentacija nizova drugacija i moguce je tijekom izvodenja programarezervirati dodatnu memoriju za podatke u nizu. Na razini pseudojezika necemo se bavititakvim detaljima. Pretpostavljat cemo da nizovi mogu imati po volji velik (konacan) brojclanova i necemo im deklarirati tip i maksimalnu duljinu.

    Jos jedan detalj koji ovisi o programskom jeziku je pocetni indeks niza. U nekimprogramskim jezicima nizovi su indeksirani od 1, tj. niz duljine n sastoji se od clanovaa[1], . . . , a[n]. U drugim programskim jezicima pocetni indeks je 0, a niz duljine n sadrziclanove a[0], . . . , a[n 1]. U pseudojeziku cemo nekad koristiti jednu, a nekad drugukonvenciju.

    Susreli smo se s algoritmima koji na ulazu uzimaju niz brojeva (primjeri 4.124.16).Svi dosadasnji primjeri probleme su rjesavali obradujuci clanove niza onim redom kojimse unose. U bilo kojem trenutku izvodenja programa u varijablama je bio pohranjen samojedan clan niza, ili najvise dva uzastopna clana u algoritmima s Fibonaccijevim brojevima(zadaci 4.184.22). Ako zelimo ispisati podatke u obrnutom redoslijedu od unesenog, iliih algoritam obraduje u nekom drugom redoslijedu, potrebno je istovremeno pamtiti svepodatke u nizu varijabli.

    Primjer 6.1. Program koji ucitava prirodan broj n i niz od n brojeva te ih ispisuje uobrnutom redoslijedu.

    53

  • 54 POGLAVLJE 6. NIZOVI I SORTIRANJE

    Rjesenje. Ako indeksi niza pocinju od 1, program izgleda ovako:

    ucitaj nza i = 1, . . . , n ponavljaj ucitaj a[i]za i = 0, . . . , n 1 ponavljaj ispisi a[n i]

    Ovo je rjesenje ako niz pocinje s indeksom 0:

    ucitaj nza i = 0, . . . , n 1 ponavljaj ucitaj a[i]za i = 1, . . . , n ponavljaj ispisi a[n i]

    Slika 6.1: Pocinju li indeksi nizova od 1 ili od 0?1

    U sljedecih nekoliko primjera nizove cemo indeksirati od 1. U iducem primjeru duljinaniza se ne ucitava na pocetku, nego se zadaje unosenjem dogovorenog podatka (nule) kojioznacava kraj niza.

    Primjer 6.2. Program koji ucitava brojeve i sprema ih u niz sve dok se ne ucita nula.Na kraju ispisuje duljinu niza, prvi i zadnji clan niza.

    Rjesenje.n 0ucitaj xdok je x 6= 0 ponavljaj n n+ 1a[n] x

    ucitaj xispisi n, a[1], a[n]

    1Strip je preuzet s web stranice http://xkcd.com/163/

  • 55

    Algoritmi iz primjera 5.15.4 rade sa znamenkama zadanog prirodnog broja. Redo-slijed kojim dolaze do znamenaka i obraduju ih ide od najmanje znacajne prema znacaj-nijima. Ako znamenke zelimo ispisati u prirodnom redoslijedu, od najznacajnije premamanje znajajnima, mozemo ih pohraniti u niz.

    Primjer 6.3. Program ucitava prirodne brojeve n i b 2. Sprema znamenke broja n ubazi b u niz i ispisuje ih od najznacajnije prema manje znacajnima.

    Rjesenje.ucitaj n, bk 0dok je n 6= 0 ponavljaj k k + 1z[k] n mod bn n div b

    za i = 0, . . . , k 1 ponavljaj ispisi z[k i]

    Vazno je razlikovati clanove niza a[1], . . . , a[n] od njihovih indeksa 1, . . . , n. Iduca triprimjera ilustriraju tu razliku.

    Primjer 6.4. Program ucitava niz od n cijelih brojeva i ispisuje sve parne clanove niza.

    Rjesenje.ucitaj nza i = 1, . . . , n ponavljaj ucitaj a[i]za i = 1, . . . , n ponavljaj[

    ako je a[i] mod 2 = 0 onda ispisi a[i]

    Ako korisnik unese niz brojeva 4, 7, 2, 6, 9, 3, 10, prethodni program ispisuje 4, 2,6, 10.

    Primjer 6.5. Program ucitava niz od n cijelih brojeva i ispisuje indekse svih parnihclanova niza.

    Rjesenje.ucitaj nza i = 1, . . . , n ponavljaj ucitaj a[i]za i = 1, . . . , n ponavljaj[