skripta za vezbe iz predmeta "strukture podataka i algoritmi 1"– ver

47
Univerzitet u Novom Sadu Prirodno-matematički fakultet Departman za matematiku i informatiku Vladimir Kurbalija, [email protected] Miloš Radovanović, [email protected] Doni Pracner, [email protected] Skripta za vežbe iz predmeta Strukture podataka i algoritmi 1 ver 14c-jk – April 2014, Novi Sad Programi u ovoj skripti su testirani sa kompajlerom ’Native XDS Modula 2’. Za verzije pre 2.60 je neophodno dodatno instalirati i TSCP (Top Speed Compatibility Pack), pošto je potreban za neke od modula koji se ne nalaze u ISO standardu Module 2. U novijim verzijama su i ovi moduli uključeni u standardnu instalaciju. Sav sadržaj se može koristiti u skladu sa CC-BY-NC-SA licencom. http://creativecommons.org/licenses/by-nc-sa/3.0/

Upload: buikien

Post on 28-Jan-2017

249 views

Category:

Documents


6 download

TRANSCRIPT

Page 1: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

Univerzitet u Novom SaduPrirodno-matematički fakultet

Departman za matematiku i informatiku

Vladimir Kurbalija, [email protected]š Radovanović, [email protected] Pracner, [email protected]

Skripta za vežbe iz predmetaStrukture podataka i algoritmi 1

ver 14c-jk – April 2014, Novi Sad

Programi u ovoj skripti su testirani sa kompajlerom ’Native XDS Modula 2’. Za verzije pre 2.60 jeneophodno dodatno instalirati i TSCP (Top Speed Compatibility Pack), pošto je potreban za neke odmodula koji se ne nalaze u ISO standardu Module 2. U novijim verzijama su i ovi moduli uključeni ustandardnu instalaciju.

Sav sadržaj se može koristiti u skladu sa CC-BY-NC-SA licencom.http://creativecommons.org/licenses/by-nc-sa/3.0/

Page 2: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

2 Strukture podataka i algoritmi 1 – skripta

Sadržaj1 Ilustracija efikasnosti algoritma 3

1.1 Zadatak: Pronaći sve pitagorine trojke do zadate granice . . . . . . . . . . . . . . . . 31.2 Zadatak: Maksimalna suma susednih elemenata u nizu . . . . . . . . . . . . . . . . . 5

2 Stringovi 8

3 Rad sa fajlovima 93.1 Modul FIO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93.2 Zadatak: ispis sadržaja fajla na ekran . . . . . . . . . . . . . . . . . . . . . . . . . . 103.3 Zadatak: spisak studenata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

4 Liste i pokazivači 134.1 Zadatak: Formiranje, štampanje i brisanje listi . . . . . . . . . . . . . . . . . . . . . . 134.2 Zadatak: Prikaz osnovih operacija nad listama . . . . . . . . . . . . . . . . . . . . . . 154.3 Zadatak: Prikaz operacija nad listama sa jedinstvenim ključem . . . . . . . . . . . . . 194.4 Zadatak: Dve liste osoba sa istim sadržajem . . . . . . . . . . . . . . . . . . . . . . . 22

5 Polinomi preko listi 245.1 Moduli . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245.2 Zadatak: Sabiranje sa unapred određenim polinomom . . . . . . . . . . . . . . . . . . 295.3 Zadatak: Suma k polinoma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

6 Stek i red opsluživanja 316.1 Primer: osnovno korišćenje steka i reda opsluživanja . . . . . . . . . . . . . . . . . . . 316.2 Zadatak: Ilustracija pisanja u fajl uz pomoć bafera . . . . . . . . . . . . . . . . . . . 316.3 Zadatak: Ispitivanje da li reč pripada gramatici wcw+ . . . . . . . . . . . . . . . . . . 346.4 Zadatak: Kalkulator za izračunavanje postfiksnih izraza . . . . . . . . . . . . . . . . . 36

7 Simulacija rekurzije 377.1 Primer 1 – faktorijel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377.2 Primer 2 – stepenovanje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387.3 Primer 3 – Fibonači . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397.4 Primer 4 – faktorijel 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 407.5 Primer 5 (ispitni) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 417.6 Primer 6 (ispitni) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

A Native XDS Modula 2 – kratko uputstvo IA.1 Mogući problemi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . II

B XDS modula 2 - rad iz komandne linije IIIB.1 Prednosti (ili “Zašto ovo raditi?”) . . . . . . . . . . . . . . . . . . . . . . . . . . . . IIIB.2 Podešavanje sistemske putanje (ili "OK, odakle početi?") . . . . . . . . . . . . . . . . IIIB.3 Kompajliranje programa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . IIIB.4 Linux i drugi slobodni sistemi (ili "Who needs windows anyway?") . . . . . . . . . . . III

Page 3: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

1 Ilustracija efikasnosti algoritma 3

1 Ilustracija efikasnosti algoritma

1.1 Zadatak: Pronaći sve pitagorine trojke do zadate granicePitagorina trojka su tri broja a, b, c za koje važi a2 + b2 = c2

MODULE Trojke1;(* Pitagorine trojke koriscenjem "Brute-force" *)FROM InOut IMPORT WriteString, WriteLn, WriteCard;CONSTGr = 100;

VARa, b, c : [1 .. Gr];

BEGINFOR a := 1 TO Gr DOFOR b := 1 TO Gr DOFOR c := 1 TO Gr DOIF a*a + b*b = c*c THENWriteLn;WriteString(’a = ’);WriteCard(a,2);WriteString(’, b = ’);WriteCard(b,2);WriteString(’, c = ’);WriteCard(c,2)

ENDEND

ENDEND

END Trojke1.

MODULE Trojke2;(*Pitagorine trojke koriscenjem zaokrugljivanja*)FROM InOut IMPORT WriteString, WriteLn, WriteCard;FROM MathLib0 IMPORT sqrt;CONSTGr = 100;

VARa, b, c : CARDINAL;creal : REAL;

BEGINFOR a := 1 TO Gr DOFOR b := 1 TO Gr DOcreal := FLOAT(a*a) + FLOAT(b*b);creal := sqrt(creal);c := TRUNC(creal);IF creal = FLOAT(c) THENWriteLn;WriteString(’ a = ’);WriteCard(a,2);WriteString(’, b = ’);WriteCard(b,2);WriteString(’, c = ’);WriteCard(c,2)

ENDEND

ENDEND Trojke2.

Sledeći primer koristi Euklidovu teoremu i malo drugačiji pristup. Ako uzmemo neka dva prirodnabroja m i n, tada se iz njih može izvesti jedna Pitagorina trojka koja lako zadovoljava potrebne uslove:

a = 2mnb = m2 − n2

c = m2 + n2

Odnosno kad probamo da proverimo da li je ovo Pitagorina trojka dobijamo:

a2 + b2=c2

(2mn)2 + (m2 − n2)2=(m2 + n2)2

Page 4: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

4 Strukture podataka i algoritmi 1 – skripta

MODULE Trojke3;(* Pitagorine trojke koriscenjem teoreme *)FROM InOut IMPORT WriteString, WriteLn, WriteCard;CONSTGr = 10;

VARa, b, c, m, n : CARDINAL;

BEGINFOR m := 1 TO Gr DOFOR n := 1 TO m-1 DOa := 2*m*n;b := m*m - n*n;c := m*m + n*n;WriteLn;WriteString(’a = ’);WriteCard(a,2);WriteString(’, b = ’);WriteCard(b,2);WriteString(’, c = ’);WriteCard(c,2)

ENDEND

END Trojke3.

Sledeća dva metoda traže trojke sa nekim specifičnim osobinama.MODULE Trojke4;(* Pitagorine trojke kod kojih je razlika

izmedju katete i hipotenuze tacno 1 *)FROM InOut IMPORT WriteString, WriteLn, WriteCard;CONSTGr = 10;

VARa, b, c, m, n : CARDINAL;

BEGINFOR m := 2 TO Gr DOn := m - 1;a := 2*m*n;b := m*m - n*n;c := m*m + n*n;WriteLn;WriteString(’a = ’);WriteCard(a,2);WriteString(’, b = ’);WriteCard(b,2);WriteString(’, c = ’);WriteCard(c,2)

ENDEND Trojke4.

MODULE Trojke5;(* Pitagorine trojke kod kojih je razlika

izmedju kateta jedan *)FROM InOut IMPORT WriteString, WriteLn, WriteCard;CONSTGr = 7;

VARa, b, c, m, n, w, i, temp : CARDINAL;

BEGINw := 1;n := 0;FOR i := 1 TO Gr DOm := n + w;a := 2*m*n;b := m*m - n*n;c := m*m + n*n;WriteLn;WriteString(’a = ’);WriteCard(a,2);WriteString(’, b = ’);WriteCard(b,2);WriteString(’, c = ’);WriteCard(c,2);temp := w;w := 3*w + 4*n;n := 2*temp + 3*n

END

Page 5: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

1.2 Zadatak: Maksimalna suma susednih elemenata u nizu 5

END Trojke5.

1.2 Zadatak: Maksimalna suma proizvoljnog broja susednih elemenata u nizucelih brojeva

MODULE MaxNiza1;(* Prvo resenje. Brute Force: O(n^3) *)FROM InOut IMPORT WriteString,ReadInt,

WriteInt,WriteCard,WriteLn;CONSTN = 10;

TYPEInterval = [1..N];

VARMax, Suma : INTEGER;d,g,i,Ood,Doo : Interval;X : ARRAY Interval OF INTEGER;

BEGINWriteString(’ Unesite niz X ’);WriteLn;FOR i := 1 TO N DOReadInt(X[i]);WriteLn

END;Max := 0;FOR d := 1 TO N DOFOR g := 1 TO N DOSuma := 0;FOR i := d TO g DOSuma := Suma + X[i]

END;IF Suma > Max THENMax := Suma;Ood := d;Doo := g

ENDEND

END;WriteLn;WriteString(’ Maksimum je ’);WriteInt(Max,3);WriteString(’ u intervalu od ’);WriteCard(Ood,3);WriteString(’ do ’);WriteCard(Doo,3)

END MaxNiza1.

MODULE MaxNiza2;(* Drugo resenje: O(n^2).

Koristi se cinjenica da je suma X[d..g]izracunljiva iz X[d..g-1]. *)

FROM InOut IMPORT WriteString,ReadInt,WriteInt,WriteCard,WriteLn;

CONSTN = 10;

TYPEInterval = [1..N];

VARMax, Suma : INTEGER;d,g,i,Ood,Doo : Interval;X : ARRAY Interval OF INTEGER;

BEGINWriteString(’ Unesite niz X ’);WriteLn;FOR i := 1 TO N DOReadInt(X[i]);WriteLn

END;Max := 0;FOR d := 1 TO N DOSuma := 0;FOR g := d TO N DOSuma := Suma + X[g];IF Suma > Max THEN

Page 6: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

6 Strukture podataka i algoritmi 1 – skripta

Max := Suma;Ood := d;Doo := g

ENDEND

END;WriteLn;WriteString(’ Maksimum je ’);WriteInt(Max,3);WriteString(’ u intervalu od ’);WriteCard(Ood,3);WriteString(’ do ’);WriteCard(Doo,3)

END MaxNiza2.

MODULE MaxNiza3;(* Trece resenje: O(n^2).

Koristi pomocni niz u kome je na i-tom mestusuma podniza x[1..i] *)

FROM InOut IMPORT WriteString,ReadInt,WriteInt,WriteCard,WriteLn;

CONSTN = 10;

TYPEInterval = [1..N];

VARMax, Suma : INTEGER;d,g,i,Ood,Doo : Interval;X : ARRAY Interval OF INTEGER;Pom : ARRAY [0..N] OF INTEGER;

BEGINWriteString(’ Unesite niz X ’);WriteLn;FOR i := 1 TO N DOReadInt(X[i]);WriteLn

END;Pom[0] := 0;FOR i := 1 TO N DOPom[i] := Pom[i-1] + X[i]

END;Max := 0;FOR d := 1 TO N DOFOR g := d TO N DOSuma := Pom[g] - Pom[d-1];IF Suma > Max THENMax := Suma;Ood := d;Doo := g

ENDEND

END;WriteLn;WriteString(’ Maksimum je ’);WriteInt(Max,3);WriteString(’ u intervalu od ’);WriteCard(Ood,3);WriteString(’ do ’);WriteCard(Doo,3)

END MaxNiza3.

MODULE MaxNiza4;(* Cetvrto resenje. Najbolje moguce: O(n) *)FROM InOut IMPORT WriteString,ReadInt,

WriteInt,WriteCard,WriteLn;CONSTN = 10;

TYPEInterval = [1..N];

VARMax, MaxDovde : INTEGER;i,d,Ood,Doo : Interval;X : ARRAY Interval OF INTEGER;

BEGINWriteString(’ Unesite niz X ’);WriteLn;

Page 7: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

1.2 Zadatak: Maksimalna suma susednih elemenata u nizu 7

FOR i := 1 TO N DOReadInt(X[i]);WriteLn

END;Max := 0;MaxDovde := 0;FOR i := 1 TO N DOIF MaxDovde = 0 THENd := i

END;MaxDovde := MaxDovde + X[i];IF MaxDovde < 0 THENMaxDovde := 0

END;IF MaxDovde > Max THENOod := d;Doo := i;Max := MaxDovde

ENDEND;WriteLn;WriteString(’ Maksimum je ’);WriteInt(Max,3);WriteString(’ u intervalu od ’);WriteCard(Ood,3);WriteString(’ do ’);WriteCard(Doo,3)

END MaxNiza4.

Page 8: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

8 Strukture podataka i algoritmi 1 – skripta

2 StringoviStringovi – odnosno nizovi znakova – ne postoje kao ugrađeni tip u jeziku Modula 2. Ovo daje

slobodu da se niz znakova definiše na dužinu najadekvatniju za konkretnu primenu. U opštem slučajudefinišemo npr:TYPE

String = ARRAY [1..30] OF CHAR;

Budući da Modula 2 definiše mogućnost korišćenja otvorenih nizova, lako je moguće definisatiprocedure koje kao parametre primaju bilo koji tip koji je definisan kao niz znakova.

PROCEDURE ObradaStringa(str: ARRAY OF CHAR);

Konkretne promenljive u programu moraju biti definisane dužine.Operacije nad stringovima se najčešće uvoze iz modula Str i one su sve definisane da prihvataju

otvorene nizove znakova kao što je malopre objašnjeno.Određivanje stvarne dužine stringa (tj koliko od maksimalnog kapaciteta niza je zapravo zauzeto

sadržajem) se može izvesti na sledeći način:duzina := Length(str)

Leksikografsko poređenje dva stringa se ne može vršiti standardnim operatorima kao što su < > =.Ovo je delom zato što se radi o nizovima, ali značajnije i zato što se ne vidi direktno koji deo niza jepopunjen “stvarnim” sadržajem. Za ovo se koristi komanda Compare, koja prihvata dva stringa kaoparametre, a vraća broj koji predstavlja njihov odnos. Taj broj će biti 0 ako su stringovi jednaki, većiod nule ako je prvi string “veći”, i manji od nule ako je prvi string “manji”.IF Compare(str1, str2) > 0 THEN

WriteString("Prvi string je veci");ELSIF Compare(str1, str2) < 0 THEN

WriteString("Prvi string je manji");ELSE (* moraju biti jednaki *)

WriteString("Jednaki su");END;

Ovo se lako pamti kad primetimo da je odnos između Compare i 0 isti kao i između prvog i drugogstringa.

Postoji i modul Strings koji ima nešto drugačije definisane procedure, no na njih se sada nećemofokusirati.

Page 9: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

3 Rad sa fajlovima 9

3 Rad sa fajlovimaZa rad sa fajlovima je bitno razumeti da su oni u suštini niz znakova, pri čemu neki imaju posebna

značenja. Na primer novi red u tekstualnom fajlu ne postoji u istom smislu kao na ekranu ili na papiru,budući da svi znakovi dolaze jedan posle drugog u jednom nizu. Umesto toga postoje specijalo definisanikodovi u ASCII tabeli znakova koji predstavljaju prelome:

• Kod 10 – Line feed – red dole na štampaču• Kod 13 – Carriage return – povratak na početak reda

Različiti operativni sistemi koriste različite kombinacije ovih znakova da označe prelome redova –Windows koristi oba jedan za drugim, Linux i drugi srodni operativni sistemi tipično koriste samo LF,dok je Apple definisao da je sam CR prelom reda. Kvalitetni tekstualni editori uglavnom mogu sami daprepoznaju prelom koji je korišćen u fajlu i da se adekvatno prilagode.

Pri radu sa fajlom se on tipično otvara preko neke pomoćne strukture koja potom pamti poziciju ufajlu odakle treba nastaviti čitanje ili gde će biti nastavljeno pisanje.

R e d 1 LF CR 2 . . .

V

Primer: tekstualni fajl u kome u prvom redu piše “Red 1”, a drugi počinje znakom “2”. Pozicijaprikazuje da smo pročitali prvi red.

Bitno je i napomenuti da ukoliko pišemo u postojeći fajl novi sadržaj zamenjuje stari – odnosno bićepisano preko starog teksta. Tipično ne postoje opcije da se novi sadržaj umeće u sredinu postojećegfajla.

3.1 Modul FIOU ovom modulu je definisan tip File, koji predstavlja jedan fajl sa kojim radimo. Da bi ga koristili

moramo ga uvesti u program (isto kao što uvozimo i komande).U primerima se pretpostavlja da je “f” tipa File, “str” niz znakova, “i” tipa INTEGER, “c” tipa

CARDINAL i “ch” tipa CHAR. Dodatna promenljiva “n” tipa INTEGER služi za formatiranje slično kao umodulu InOut, odnosno za ispis će biti zauzeto bar “n” znakova.

Ako otvaramo već postojeći fajl, poželjno je prvo proveriti da li on postoji – u suprotnom naš programće se srušiti pri izvršavanju. Funkcija Exists(str) vraća da li fajl postoji.

Promenljiva tipa File se mora vezati za neki fajl jednom od sledećih komandi:

• f := Open(str); – otvara se postojeci fajl za čitanje• f := Create(str); – kreira se fajl za pisanje; ako je već postojao, biće zamenjen• f := Append(str); – otvara se postojeći fajl za dopisivanje na kraj

Po završetku rada fajl se mora zatvoriti, u našem primeru to bi bilo:

• Close(f);

Procedure za čitanje i pisanje su vrlo slične onima iz modula IO, osim što imaju dodatni parametar„f“ koji označava fajl sa kojim se radi.

• RdStr(f,str) – učitava ceo red u string str• RdItem(f,str) – učitava jednu reč u string str (učitava znakove iz fajla dok ne naiđe naseparator)

• i:= RdInt(f); c:= RdCard(f) – učitava broj, koji se dobija kao rezultat procedure• ch:= RdChar(f) – vraća jedan znak iz fajla

Bitno je obratiti pažnju na specifičnost da postoje dve komande za čitanje stringova iz fajla i da seone ponašaju različito. Budući da razmak spada u separatore to znači da se korišćenjem RdItem nemože učitati string koji ima u sebi razmake.

Analogne su i procedure za pisanje različitih tipova u fajl:

• WrStr(f,str);• WrInt(f,i,n);• WrCard(f,c,n);• WrChar(f,ch);

Page 10: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

10 Strukture podataka i algoritmi 1 – skripta

Treba primetiti da ne postoje dve komande za ispis stringa u fajl – potpuno je svejedno da li on imarazmake u sebi ili ne.

Prelom reda se eksplicitno upisuje u fajl komandom

• WrLn(f);.

Da bi odredili da li smo stigli do kraja fajla možemo koristiti EOF. U pitanju je logička promenljivakoja se uvozi iz modula FIO kao bilo kakva normalna komanda. Ona označava da li smo poslednjomoperacijom čitanja stigli do kraja fajla. Ne menja joj se vrednost pri operacijama otvaranja i zatvaranjafajlova, odnosno neće se pri tome resetovati na FALSE, pa na ovo treba obratiti pažnju pri radu.

Mogući problemi

U ovoj glavi će biti navedeni neki česti problemi koji se mogu desiti pri korišćenju FIO modula, akoji su vezani za konkretnu implementaciju u XDS distribuciji kompajlera.

RdStr i drugi pozivi Prilikom čitanja iz fajlova može doći do neobičnih rezultata ako se kombinujupozivi RdStr sa drugima. Problem je u različitom tretiranju separatora. Komanda RdStr uvek čitado kraja reda i pri tome premesti poziciju za čitanje odmah iza znaka za razdvajanje redova. Ostalekomande prvo preskaču separatore i čitaju sadržaj dok ne naiđu na novi separator (što može biti novi red,a može biti i razmak, tabulator i neki drugi znaci) i staju sa čitanjem pre tog separatora. Kombinovanjeova dva pristupa može dovesti do toga da RdStr nakon neke druge komande učita samo kraj trenutnogreda, a ne sledeći red kao što bi bilo očekivano.

EOF i prazan red na kraju fajla Svako čitanje iz fajla postavlja EOF u skladu sa tim da li je komandastigla do kraja fajla ili ne. Nažalost kod svih komandi za čitanje (osim RdStr) postoji problem ukolikoje na kraju prazan red ili neki dodatni separator. Tada učitavanje poslednjeg elementa nije zapravodošlo do kraja fajla. Ako se nakon toga proba još jedno učitavanje sa takvom komandom ona će probatida preskoči separator i da učita neki sadržaj, ali će se zaglaviti jer ne može da ga nađe. Ovo ponašanjeje greška u implementaciji FIO modula u okviru XDS distribucije.

3.2 Zadatak: ispis sadržaja fajla na ekranPotrebno je sve redove iz fajla učitati i ispisati ih na ekran.

MODULE ispis;FROM FIO IMPORT File, Exists, Open, Close, EOF, RdStr;FROM InOut IMPORT WriteString, WriteLn, ReadString;

PROCEDURE ispisF(ime: ARRAY OF CHAR);VARf:File;s : ARRAY[1..100] OF CHAR;

BEGINIF Exists(ime) THENf:=Open(ime);EOF := FALSE;WHILE NOT EOF DO

RdStr(f,s);WriteString(s);WriteLn;

END;Close(f);

ELSEWriteString("-- fajl ne postoji --");WriteLn;

END;END ispisF;

VARime: ARRAY[1..100] OF CHAR;

BEGINWriteString("unesite ime fajla:");ReadString(ime);ispisF(ime);

END ispis.

Page 11: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

3.3 Zadatak: spisak studenata 11

3.3 Zadatak: spisak studenataNapraviti program koji iz fajla učitava podatke o studentima, dodaje novog studenta u spisak i

snima fajl. U fajlu se u svakom redu nalazi podatak o jednom studentu, redom prezime, ime i godinarođenja, razdvojeni razmacima.MODULE nizslog;FROM InOut IMPORT WriteString, WriteLn, WriteCard,

ReadCard, ReadString;FROM FIO IMPORT File, Exists, Open, Create, Close, EOF,

RdItem, RdCard, WrStr, WrCard, WrLn;FROM Str IMPORT Compare;

CONSTMaxStud = 100;radnifajl = "studenti.txt";

TYPEString = ARRAY[1..30] OF CHAR;Student = RECORD

ime, prez: String;god: CARDINAL;

END;Studenti = ARRAY[1..MaxStud] OF Student;

PROCEDURE UcitajF(fajl:String;VAR spisak: Studenti; VAR n:CARDINAL);

VARf:File;

BEGINn:=0;IF Exists(fajl) THEN

f:= Open(fajl);EOF := FALSE;WHILE NOT EOF DO

INC(n);RdItem(f, spisak[n].prez);RdItem(f, spisak[n].ime);spisak[n].god := RdCard(f);

END;Close(f);

END;END UcitajF;

PROCEDURE Ispisi(spisak:Studenti; n:CARDINAL);VAR

i: CARDINAL;BEGIN

FOR i:=1 TO n DOWriteString(spisak[i].prez);WriteString(" ");WriteString(spisak[i].ime);WriteString(" ");WriteCard(spisak[i].god,1);WriteLn;

END;END Ispisi;

PROCEDURE IspisiF(fajl:String;spisak:Studenti; n:CARDINAL);

VARf:File;i: CARDINAL;

BEGINIF (n>0) AND (n<=MaxStud) THEN

f:=Create(fajl);(* pravimo takav fajl da ne

postoji zadnji prazan red *)FOR i:=1 TO n-1 DO

WrStr(f,spisak[i].prez);WrStr(f," ");WrStr(f,spisak[i].ime);WrStr(f," ");WrCard(f,spisak[i].god,1);WrLn(f);

END;WrStr(f,spisak[n].prez);WrStr(f," ");

Page 12: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

12 Strukture podataka i algoritmi 1 – skripta

WrStr(f,spisak[n].ime);WrStr(f," ");WrCard(f,spisak[n].god,1);Close(f);

END;END IspisiF;

PROCEDURE NoviStudent(VAR spisak:Studenti; VAR n:CARDINAL);VAR

stud,temp:Student;i:CARDINAL;dodaj:BOOLEAN;

BEGINIF n<MaxStud THEN

WriteString("Prezime novog studenta?");ReadString(stud.prez);WriteString("Ime novog studenta?");ReadString(stud.ime);WriteString("God. rodj. novog studenta?");ReadCard(stud.god);(* proverimo da li vec postoji *)i:=1;dodaj := TRUE;WHILE (i<=n) AND dodaj DO

temp := spisak[i];IF (temp.god = stud.god) &(Compare(temp.prez,stud.prez)=0) &(Compare(temp.ime,stud.ime)=0) THENdodaj:=FALSE;

END;INC(i);

END;IF dodaj THEN

INC(n);spisak[n]:=stud;

ELSEWriteString("podaci vec postoje!");

END;ELSE

WriteString("popunjen kapacitet!");END;

END NoviStudent;

VARspisak : Studenti;n:CARDINAL;

BEGINUcitajF(radnifajl, spisak, n);Ispisi(spisak, n);NoviStudent(spisak,n);IspisiF(radnifajl, spisak, n);

END nizslog.

Page 13: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

4 Liste i pokazivači 13

4 Liste i pokazivačiZa rad sa pokazivačima je potrebno iz modula Storage uvesti procedure za dinamičko zauzimanje

i oslobađanje memorije ALLOCATE i DEALLOCATE.U kodu se mogu koristiti i skraćeni oblici NEW i DISPOSE koji se direktno prevode u prethodno

pomenute procedure.ALLOCATE(point, SIZE(point)); (* isto kao NEW(point) *)DEALLOCATE(point, SIZE(point)); (* isto kao DISPOSE(point) *)

4.1 Zadatak: Formiranje, štampanje i brisanje listi

MODULE liste;FROM InOut IMPORT WriteString, WriteLn, WriteInt,

ReadInt, ReadCard;FROM Storage IMPORT ALLOCATE, DEALLOCATE;TYPEbrojevi = POINTER TO brojSlog;brojSlog = RECORD

info:INTEGER;veza:brojevi;

END;VARn,i:CARDINAL;lista : brojevi;br:INTEGER;

PROCEDURE DodajPoc(VAR lista:brojevi; br:INTEGER);(* dodaje broj br na pocetak liste *)VARtemp:brojevi;

BEGINNEW(temp);temp^.info := br;temp^.veza := lista;lista := temp;

END DodajPoc;

PROCEDURE Stampaj(lista:brojevi);VARtemp:brojevi;

BEGINtemp:=lista;WHILE temp # NIL DO

WriteInt(temp^.info,0);WriteLn;temp := temp^.veza;

END;END Stampaj;

PROCEDURE Unisti(VAR lista:brojevi);VARtemp:brojevi;

BEGINtemp:=lista;WHILE temp # NIL DO

lista:=lista^.veza;DISPOSE(temp);temp:=lista;

END;END Unisti;

BEGINlista := NIL;WriteString(’unesite n (broj brojeva): ’);ReadCard(n);WriteString(’unesite brojeve: ’);WriteLn;FOR i:= 1 TO n DO

ReadInt(br);DodajPoc(lista,br);

END;WriteString(’sadrzaj liste:’);WriteLn;

Page 14: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

14 Strukture podataka i algoritmi 1 – skripta

Stampaj(lista);Unisti(lista);WriteString(’memorija je oslobodjena’);WriteLn;

END liste.

Alternativno je poziv DodajPoc moguće zameniti pozivom jedne od sledeće dve procedure čime sedobija dodavanje elementa na kraj liste, ili kreiranje sortirane liste:

PROCEDURE DodajKraj(VAR lista:brojevi; br:INTEGER);(* dodaje element na kraj liste *)VARtekuci, temp :brojevi;

BEGINNEW(temp);temp^.info := br;temp^.veza := NIL;IF lista = NIL THEN

(* prazna lista *)lista:=temp;

ELSEtekuci := lista;WHILE tekuci^.veza#NIL DO

tekuci:=tekuci^.veza;END;tekuci^.veza := temp;

END;END DodajKraj;

PROCEDURE DodajSort(VAR lista:brojevi; br:INTEGER);(* dodaje broj tako da lista ostane sortirana

(podrazumeva se da je vec sortirana) *)VARtemp, tekuci : brojevi;

BEGINNEW(temp);temp^.info:=br;temp^.veza:=NIL;IF (lista = NIL) OR (lista^.info>=br) THEN(*prazna lista ili na pocetak*)temp^.veza:=lista;lista := temp;

ELSE(*negde u listi*)tekuci:= lista;WHILE (tekuci^.veza # NIL) AND

(tekuci^.veza^.info<=br) DOtekuci:=tekuci^.veza;

END;temp^.veza := tekuci^.veza;tekuci^.veza:=temp;

END;END DodajSort;

Kod svih procedura se mogu primeniti i rekurzivne varijante. Sledi primer za kreiranje sortirane liste.

PROCEDURE DodajSortRek(VAR lista:brojevi; br:INTEGER);(* Koristi se cinjenica da prosledjujemo pokazivacpo referenci, tj. da ga mozemo menjati unutar procedure *)VARtemp : brojevi;

BEGINIF (lista = NIL) OR (lista^.info>=br) THEN(* Izlaz iz rekurzije. Ubacivanje u praznu listu,na kraj liste ili na odgovarajuce mesto *)NEW(temp);temp^.info:=br;temp^.veza:=lista;lista:=temp;

ELSEDodajSortRek(lista^.veza, br);

END;END DodajSortRek;

Page 15: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

4.2 Zadatak: Prikaz osnovih operacija nad listama 15

4.2 Zadatak: Prikaz osnovih operacija nad listama

MODULE liste2;FROM InOut IMPORT WriteString, WriteLn,

WriteCard, ReadCard;FROM IO IMPORT RdKey;FROM Storage IMPORT ALLOCATE, DEALLOCATE;TYPEskupZn = SET OF CHAR;brojevi = POINTER TO brojSlog;brojSlog = RECORD

info:CARDINAL;veza:brojevi;

END;VARlista : brojevi;menu,prazno:CHAR;

PROCEDURE DodajPoc(VAR lista:brojevi; br:INTEGER);(* dodaje broj pom na pocetak liste *)VARtemp:brojevi;

BEGIN(* kreiramo novi element *)NEW(temp);temp^.info := br;(* treba da pokazuje na ostatak liste *)temp^.veza := lista;(* pocetak liste je novi element *)lista := temp;

END DodajPoc;

PROCEDURE Unos(VAR lista:brojevi);(* dodaje n brojeva u listu *)VARn,i,br:CARDINAL;

BEGINWriteString(’unesite n (broj brojeva): ’);ReadCard(n);FOR i:= 1 TO n DO

WriteString("unesite broj ");WriteCard(i,0);WriteString(": ");ReadCard(br);DodajPoc(lista,br);

END;END Unos;

(* -- procedure za stampu -- *)

PROCEDURE Stampaj(lista:brojevi);(* stampa sadrzaj liste na ekran *)VARtemp:brojevi;

BEGINWriteLn;WriteString("Sadrzaj liste:");WriteLn;temp:=lista;WHILE temp # NIL DO

WriteCard(temp^.info,0);WriteLn;temp := temp^.veza;

END;END Stampaj;

PROCEDURE StampajK(VAR lista:brojevi);(* stampa k-ti element (k unosi korisnik) *)VARtemp:brojevi;k,brojac:CARDINAL;

BEGINWriteString("unesite redni broj elementa:");ReadCard(k);temp:=lista;brojac := 1;

Page 16: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

16 Strukture podataka i algoritmi 1 – skripta

WHILE (temp# NIL) AND (k>brojac) DOtemp:=temp^.veza;INC(brojac);

END;IF (temp#NIL) THENWriteCard(temp^.info,2);

ELSEWriteString("greska! - ne postoji element");WriteString(" u listi sa rednim brojem ");WriteCard(k,2);

END;WriteLn();

END StampajK;

PROCEDURE StampajMinimum(VAR lista:brojevi);(* nalazi i stampa minimalni element liste *)VARtemp:brojevi;min:CARDINAL;

BEGINIF (lista=NIL) THENWriteString("prazna lista!");

ELSEmin:=lista^.info;temp:=lista^.veza;WHILE temp # NIL DOIF temp^.info < min THENmin := temp^.info;

END;temp := temp^.veza;

END;WriteString("Minimalni element liste je ");WriteCard(min,0);

END;WriteLn;

END StampajMinimum;

(* -- pomocne procedure, bez ispisa -- *)

PROCEDURE UListi(lista:brojevi;br: CARDINAL):BOOLEAN;

(* vraca da li se ’br’ nalazi u listi ’lista’ *)VARtemp:brojevi;

BEGINtemp:=lista;WHILE (temp # NIL) AND (temp^.info # br) DO(* dok ne dodjemo do kraja liste

ili ne nadjemo broj *)temp := temp^.veza;

END;IF temp#NIL THEN(* znaci da nismo na kraju liste,

tj da je nadjen broj *)RETURN TRUE;

ELSE (* temp = NIL *)RETURN FALSE;

END;END UListi;

PROCEDURE IzbaciIzListe(VAR lista:brojevi;br: CARDINAL):BOOLEAN;

(* izbacuje broj ’br’ iz liste, naravno akopostoji i vraca da li je operacija uspesnoobavljena *)

VARtemp,prethodni:brojevi;

BEGIN(* proverimo da li je prvi element *)IF (lista # NIL) AND (lista^.info = br) THENtemp:=lista;lista :=lista^.veza;DISPOSE(temp);RETURN TRUE;

ELSE(* trazimo u ostatku liste *)

Page 17: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

4.2 Zadatak: Prikaz osnovih operacija nad listama 17

temp:=lista;prethodni:=NIL;WHILE (temp # NIL) AND (temp^.info # br) DO

(* dok ne dodjemo do kraja listeili ne nadjemo broj *)

prethodni:=temp;temp := temp^.veza;

END;IF temp#NIL THEN(* znaci da nismo na kraju liste,

odnosno da smo nasli broj *)(* prevezemo listu oko elementa *)prethodni^.veza:=temp^.veza;DISPOSE(temp);RETURN TRUE;

ELSERETURN FALSE;

END;END;

END IzbaciIzListe;

PROCEDURE IzbaciIzListeSve(VAR lista:brojevi;br: CARDINAL):CARDINAL;

(* izbacuje sve brojeve ’br’ iz liste, naravno akopostoje i vraca koliko ih je bilo *)

VARtemp,prethodni:brojevi;brojac : CARDINAL;

BEGINbrojac := 0;(* uklanjamo sa pocetka koliko je potrebno *)WHILE (lista # NIL) AND (lista^.info = br) DOtemp:=lista;lista :=lista^.veza;DISPOSE(temp);INC(brojac);

END;(* trazimo u ostatku liste *)IF (lista # NIL) THENtemp:=lista;WHILE (temp^.veza # NIL) DO

(* idemo do poslednjeg elementa liste *)prethodni:=temp;temp := temp^.veza;IF temp^.info = br THEN(* prevezemo listu oko elementa *)prethodni^.veza:=temp^.veza;DISPOSE(temp);INC(brojac);(* vracamo se jedan korak da biu novom krugu proverili i ovaj element *)temp := prethodni;

END;END;

END;RETURN brojac;

END IzbaciIzListeSve;

(* - procedure sa interakcijom sa korisnikom - *)

PROCEDURE IzbacivanjeEl(VAR lista:brojevi);(* izbacuje uneti broj iz liste koristeci proceduru IzbaciIzListe *)VARbr:CARDINAL;

BEGINWriteString("unesite broj za izbacivanje: ");ReadCard(br);IF IzbaciIzListe(lista,br) THENWriteString("broj je izbacen iz liste");

ELSEWriteString("greska! - broj ne postoji");

END;WriteLn;

END IzbacivanjeEl;

PROCEDURE IzbacivanjeElSvi(VAR lista:brojevi);

Page 18: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

18 Strukture podataka i algoritmi 1 – skripta

(* izbacuje sve primeke unetog broj iz listekoristeci proceduru IzbaciIzListeSve *)

VARbr, ukupno:CARDINAL;

BEGINWriteString("unesite broj za izbacivanje: ");ReadCard(br);ukupno := IzbaciIzListeSve(lista,br);WriteString("Iz liste je izbaceno ");WriteCard(ukupno,3);WriteString(" el.");WriteLn;

END IzbacivanjeElSvi;

PROCEDURE IzbacivanjeK(VAR lista:brojevi);(* izbacuje k-ti element iz liste *)VARtemp,tekuci:brojevi;k,brojac:CARDINAL;

BEGINIF lista=NIL THENWriteString("lista je prazna, nema ");WriteString("elemenata za izbacivanje");

ELSEWriteString("unesite redni broj elementa");WriteString(" koji zelite izbaciti:");ReadCard(k);IF k=1 THEN (*izbacivanje prvog *)temp:=lista;lista := lista^.veza;DISPOSE(temp);

ELSEtekuci := lista;brojac := 2; (*gledamo jedan unapred*)WHILE (tekuci^.veza# NIL) AND (k>brojac) DO(* idemo kroz listu do k-tog el *)tekuci:=tekuci^.veza;INC(brojac);

END;IF (tekuci^.veza#NIL) THEN

(* pamtimo element za brisanje *)temp:=tekuci^.veza;(* prevezujemo listu oko njega*)tekuci^.veza:=tekuci^.veza^.veza;DISPOSE(temp);

ELSEWriteString("greska! - ne postoji el ");WriteString("u listi sa rednim brojem ");WriteCard(k,2);

END;WriteLn();

END;END;

END IzbacivanjeK;

PROCEDURE Pretraga(lista:brojevi);(* provera da li se uneti broj nalazi u listi *)VARbr:CARDINAL;

BEGINWriteString("unesite trazeni broj");ReadCard(br);IF UListi(lista,br) THENWriteString("broj postoji u listi");

ELSEWriteString("broj ne postoji u listi");

END;WriteLn;

END Pretraga;

(* -- oslobadjanje memorije -- *)

PROCEDURE Unisti(VAR lista:brojevi);VARtemp:brojevi;

BEGIN

Page 19: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

4.3 Zadatak: Prikaz operacija nad listama sa jedinstvenim ključem 19

temp:=lista;WHILE temp # NIL DO

lista:=lista^.veza;DISPOSE(temp);temp:=lista;

END;END Unisti;

BEGIN(* pocinjemo od prazne liste *)lista := NIL;REPEAT

WriteLn;WriteString("Ilustracija rada sa");WriteString(" listama brojeva");WriteLn;WriteString("=============================");WriteLn;WriteString("s - Stampa");WriteLn;WriteString("u - Unos");WriteLn;WriteString("i - Izbacivanje br iz liste");WriteLn;WriteString("v - izbacivanje svih br iz liste");WriteLn;WriteString("e - izbacivanje k-tog El.");WriteLn;WriteString("k - stampanje k-tog elementa");WriteLn;WriteString("m - Minimalni broj u listi");WriteLn;WriteString("p - Pretraga el. u listi");WriteLn;WriteLn;WriteString("q - kraj rada (Quit)");WriteLn;REPEATmenu := CAP(RdKey());

UNTIL menu IN skupZn{’S’,’U’,’E’,’I’,’V’,’M’,’K’,’P’,’Q’};

IF menu#’Q’ THENCASE menu OF’S’ : Stampaj(lista);|’U’ : Unos(lista);|’I’ : IzbacivanjeEl(lista);|’V’ : IzbacivanjeElSvi(lista);|’E’ : IzbacivanjeK(lista);|’K’ : StampajK(lista); |’M’ : StampajMinimum(lista); |’P’ : Pretraga(lista);|END;WriteLn;WriteString("--- pritisnite bilo koji ");WriteString("taster za povratak u meni");prazno:=RdKey();

ELSEWriteString("Kraj rada")

END;WriteLn;

UNTIL menu=’Q’;Unisti(lista);

END liste2.

4.3 Zadatak: Prikaz operacija nad listama sa jedinstvenim ključem

MODULE Radnici;

FROM InOut IMPORT WriteString, ReadString,WriteLn, WriteCard, ReadCard, Done;

FROM IO IMPORT RdKey;FROM Storage IMPORT ALLOCATE, DEALLOCATE;

TYPEskupZn = SET OF CHAR;str = ARRAY [1..20] OF CHAR;radnici = POINTER TO slog;slog = RECORD

ime, prez : str;

Page 20: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

20 Strukture podataka i algoritmi 1 – skripta

broj : CARDINAL;sled : radnici

END;VARmeni, pom : CHAR;rad : radnici;

PROCEDURE Clear();VARbr: CARDINAL;

BEGINFOR br:=1 TO 100 DOWriteLn;

END;END Clear;

PROCEDURE Spisak(rad : radnici);BEGINWHILE rad # NIL DOWriteString(rad^.ime);WriteString(’ ’);WriteString(rad^.prez);WriteCard(rad^.broj, 8);WriteLn;rad := rad^.sled

ENDEND Spisak;

PROCEDURE Zaposli(VAR rad : radnici);VARnovi, tek : radnici;nadjen : BOOLEAN;

BEGINNEW(novi);REPEATWriteString(’Ime, prezime i jedinstveni’);WriteString(’ broj novog radnika: ’);WriteLn;ReadString(novi^.ime);ReadString(novi^.prez);ReadCard(novi^.broj);nadjen := FALSE;tek := rad;WHILE NOT nadjen AND (tek # NIL) AND

(tek^.broj <= novi^.broj) DOIF novi^.broj = tek^.broj THENnadjen := TRUE

ELSEtek := tek^.sled

ENDEND

UNTIL Done AND NOT nadjen;IF (rad = NIL) OR (novi^.broj<rad^.broj) THENnovi^.sled := rad;rad := novi

ELSEtek := rad;WHILE (tek^.sled # NIL) AND

(tek^.sled^.broj < novi^.broj) DOtek := tek^.sled

END;novi^.sled := tek^.sled;tek^.sled := novi

ENDEND Zaposli;

PROCEDURE Otpusti(VAR rad : radnici);VARtek, pom : radnici;br : CARDINAL;

BEGINREPEATWriteLn;WriteString(’Unesite redni broj radnika:’);ReadCard(br)

UNTIL Done;

Page 21: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

4.3 Zadatak: Prikaz operacija nad listama sa jedinstvenim ključem 21

WriteLn;IF rad = NIL THENWriteString(’Greska.’)

ELSIF br = rad^.broj THENpom := rad;rad := rad^.sled;DISPOSE(pom)

ELSEtek := rad;WHILE (tek^.sled # NIL) AND

(tek^.sled^.broj < br) DOtek := tek^.sled

END;IF (tek^.sled = NIL) OR

(tek^.sled^.broj > br) THENWriteString(’Greska.’)

ELSEpom := tek^.sled;tek^.sled := tek^.sled^.sled;DISPOSE(pom)

ENDEND

END Otpusti;

PROCEDURE Inform(rad : radnici);VARbr : CARDINAL;

BEGINREPEATWriteLn;WriteString(’Unesite redni broj radnika:’);ReadCard(br)

UNTIL Done;WriteLn;WHILE (rad # NIL) AND (rad^.broj < br) DOrad := rad^.sled

END;IF (rad = NIL) OR (rad^.broj # br) THENWriteString(’Greska.’)

ELSEWriteString(rad^.ime);WriteString(’ ’);WriteString(rad^.prez)

ENDEND Inform;

PROCEDURE Bankrot(VAR rad : radnici);VARpom : radnici;

BEGINWHILE rad # NIL DOpom := rad;rad := rad^.sled;DISPOSE(pom)

ENDEND Bankrot;

BEGINrad := NIL;REPEATClear;WriteString(’s - spisak svih zaposlenih’);WriteLn;WriteString(’z - zaposljavanje radnika’);WriteLn;WriteString(’o - otpustanje radnika’);WriteLn;WriteString(’i - informacije o radniku’);WriteLn;WriteString(’b - bankrot firme’);WriteLn;WriteString(’k - kraj rada’);WriteLn;REPEATmeni := RdKey();

UNTIL CAP(meni) IN skupZn{’S’, ’Z’, ’O’,

Page 22: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

22 Strukture podataka i algoritmi 1 – skripta

’I’, ’B’, ’K’};Clear;IF CAP(meni) # ’K’ THENCASE CAP(meni) OF’S’ : Spisak(rad)|’Z’ : Zaposli(rad)|’O’ : Otpusti(rad)|’I’ : Inform(rad)|’B’ : Bankrot(rad)

END;WriteLn;WriteString(’-- pritisnite bilo koji ’);WriteString(’taster za nastavak --’);pom := RdKey()

ENDUNTIL CAP(meni) = ’K’

END Radnici.

Procedura Spisak se može realizovati i u rekurzivnoj verziji:PROCEDURE Spisak(rad : radnici);BEGINIF rad # NIL THENWriteString(rad^.ime);WriteString(’ ’);WriteString(rad^.prez);WriteCard(rad^.broj, 8);WriteLn;Spisak(rad^.sled)

ENDEND Spisak;

4.4 Zadatak: Dve liste osoba koje dele sadržaj, jedna sortirana po visini,druga po težini

Sa tastature učitavati po dva broja koji opisuju osobu (visina i težina) i smeštati ih u povezane listu,tako da postoji neopadajuće uređenje i po visini i po težini.MODULE VisTez;FROM Storage IMPORT ALLOCATE, DEALLOCATE;FROM IO IMPORT WrLn, WrStr, RdCard, WrCard;FROM SYSTEM IMPORT TSIZE;TYPEpok = POINTER TO element;element = RECORD

visina, tezina : CARDINAL;Vveza, Tveza : pok

END;VARpocV, pocT : pok;vis, tez : CARDINAL;

PROCEDURE Ispisi(pocV, pocT : pok);VARtek : pok;

BEGINtek := pocV;WrStr(’Po visini:’);WrLn;WHILE tek # NIL DOWrCard(tek^.visina, 6);tek := tek^.Vveza

END;WrLn;tek := pocT;WrStr(’Po tezini:’);WrLn;WHILE tek # NIL DOWrCard(tek^.tezina,6);tek := tek^.Tveza

ENDEND Ispisi;

PROCEDURE Ubaci(VAR pocV, pocT : pok;vis, tez : CARDINAL);

VARnovi, tek, iza : pok;nadjen : BOOLEAN;

Page 23: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

4.4 Zadatak: Dve liste osoba sa istim sadržajem 23

BEGINIF pocV = NIL THENALLOCATE(pocV, TSIZE(element));pocV^.visina := vis;pocV^.tezina := tez;pocV^.Vveza := NIL;pocV^.Tveza := NIL;pocT := pocV

ELSEALLOCATE(novi, TSIZE(element));novi^.visina := vis;novi^.tezina := tez;tek := pocV;nadjen := FALSE;WHILE (tek # NIL) AND NOT nadjen DOnadjen := vis <= tek^.visina;IF NOT nadjen THENiza := tek;tek := tek^.Vveza

ENDEND;novi^.Vveza := tek;IF tek = pocV THENpocV := novi

ELSEiza^.Vveza := novi

END;tek := pocT;nadjen := FALSE;WHILE (tek # NIL) AND NOT nadjen DOnadjen := tez <= tek^.tezina;IF NOT nadjen THENiza := tek;tek := tek^.Tveza

ENDEND;novi^.Tveza := tek;IF tek = pocT THENpocT := novi

ELSEiza^.Tveza := novi

ENDEND

END Ubaci;

BEGINpocV := NIL;pocT := NIL;WrStr(’Unesite visinu ---- ’);vis := RdCard();WHILE vis > 0 DOWrStr(’Unesite tezinu ---- ’);tez := RdCard();Ubaci(pocV, pocT, vis, tez);WrLn;WrStr(’Unesite visinu ---- ’);vis := RdCard()

END;WrLn;Ispisi(pocV, pocT)

END VisTez.

Page 24: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

24 Strukture podataka i algoritmi 1 – skripta

5 Polinomi preko listi5.1 Moduli

Polinomi su predstavljeni pomoću pokazivača. Apstraktni tip podataka Polinom je definisan uglobalnom modulu. Redosled parametara kod svih procedura je takav da varijabilni parametri dolazena kraju.

PolinomL.DEF(* Modul za rad sa polinomima preko listi

verzija 2014; rev 1 *)DEFINITION MODULE PolinomL;TYPEPolinom = POINTER TO Monom;Monom = RECORD

k : REAL;st : CARDINAL;veza : Polinom

END;

PROCEDURE Anuliraj(VAR p: Polinom);PROCEDURE Unos(VAR p: Polinom);PROCEDURE Stampaj(p: Polinom; d: CARDINAL);PROCEDURE Kopiraj(p: Polinom;

VAR kopija: Polinom);PROCEDURE PostaviClan(k: REAL; st:CARDINAL;

VAR p:Polinom);PROCEDURE KoeficijentUz(p:Polinom; st:CARDINAL):REAL;PROCEDURE MaksimalniStepen(p:Polinom):CARDINAL;PROCEDURE UbaciMonom(mon:Polinom;

VAR p: Polinom);PROCEDURE PromeniZnak(VAR p: Polinom);PROCEDURE Saberi(p1, p2: Polinom;

VAR zbir: Polinom);PROCEDURE SaberiNa(p: Polinom; VAR rez: Polinom);PROCEDURE Oduzmi(p1,p2: Polinom;

VAR razlika: Polinom);PROCEDURE MonomPuta(p, mon: Polinom;

VAR mp : Polinom);PROCEDURE Puta(p1, p2: Polinom; VAR pr: Polinom);PROCEDURE Kolicnik(p1, p2: Polinom;

VAR kol, ost: Polinom;VAR ok : BOOLEAN);

PROCEDURE PolinomNaN(p: Polinom; n: CARDINAL;VAR rez: Polinom);

PROCEDURE DisposePolinom(VAR p: Polinom);

END PolinomL.

PolinomL.MOD(* Modul za rad sa polinomima preko listi

verzija 2014; rev 1 *)IMPLEMENTATION MODULE PolinomL;FROM InOut IMPORT Write, WriteString, WriteLn,

WriteCard, ReadCard, Done;FROM RealInOut IMPORT WriteReal, ReadReal;FROM Storage IMPORT ALLOCATE, DEALLOCATE;

PROCEDURE Anuliraj(VAR p: Polinom);BEGINp := NIL;

END Anuliraj;

PROCEDURE Kopiraj(p: Polinom; VAR kopija: Polinom);VARpomocni: Polinom;

BEGINIF p = NIL THENkopija := NIL

ELSENEW(kopija);kopija^ := p^;

Page 25: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

5.1 Moduli 25

p := p^.veza;pomocni := kopija;WHILE p <> NIL DONEW(pomocni^.veza);pomocni := pomocni^.veza;pomocni^ := p^;p := p^.veza

ENDEND

END Kopiraj;

PROCEDURE Stampaj(p: Polinom; d: CARDINAL);

PROCEDURE StampajMonom(m : Polinom);BEGINWITH m^ DOIF st <> 0 THENIF ABS(k) <> 1.0 THENWriteReal(ABS(k), d)

END;Write(’x’);IF st <> 1 THENWrite(’^’);WriteCard(st, 1)

ENDELSEWriteReal(ABS(k), d)

ENDEND

END StampajMonom;

BEGINIF p = NIL THENWriteReal(0., d)

ELSEIF p^.k < 0.0 THENWriteString(’ - ’)

END;StampajMonom(p);p := p^.veza;WHILE p <> NIL DOIF p^.k > 0.0 THENWriteString(’ + ’)

ELSEWriteString(’ - ’)

END;StampajMonom(p);p := p^.veza

ENDEND

END Stampaj;

PROCEDURE PostaviClan(k:REAL; st:CARDINAL;VAR p:Polinom);

VARcilj, prethodni : Polinom;

BEGINcilj := p;prethodni := NIL;WHILE (cilj # NIL) AND (cilj^.st>st) DOprethodni := cilj;cilj := cilj^.veza;

END;(* da li upisujemo vrednost ili sklanjamo clan *)IF k#0.0 THEN(* da li menjamo clan ili pravimo novi *)IF (cilj # NIL) AND (cilj^.st = st) THENcilj^.k:=k;

ELSENEW(cilj);cilj^.k := k;cilj^.st := st;cilj^.veza := NIL;IF prethodni = NIL THEN(* ili je prazan polinom, ili dodajemo na pocetak *)cilj^.veza := p;

Page 26: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

26 Strukture podataka i algoritmi 1 – skripta

p := cilj;ELSEcilj^.veza := prethodni^.veza;prethodni^.veza := cilj;

END;END;

ELSE(* da li postoji ovakav clan *)IF (cilj # NIL) AND (cilj^.st = st) THENIF p = cilj THENp := p^.veza;

ELSEprethodni^.veza:= prethodni^.veza^.veza;

END;DISPOSE(cilj);

END;END;

END PostaviClan;

PROCEDURE KoeficijentUz(p:Polinom; st:CARDINAL):REAL;VARtekuci : Polinom;

BEGINtekuci := p;WHILE (tekuci#NIL) AND (tekuci^.st > st) DOtekuci := tekuci^.veza;

END;IF (tekuci # NIL) AND (tekuci^.st = st) THENRETURN tekuci^.k;

ELSERETURN 0.0;

END;END KoeficijentUz;

PROCEDURE MaksimalniStepen(p:Polinom):CARDINAL;BEGINIF p#NIL THENRETURN p^.st;

ELSERETURN 0;

END;END MaksimalniStepen;

PROCEDURE UbaciMonom(mon:Polinom; VAR p: Polinom);VARstari, tekuci, kopija: Polinom;

BEGINIF mon # NIL THENNEW(kopija);kopija^ := mon^;tekuci := p;

stari := NIL;WHILE (tekuci#NIL) AND (tekuci^.st>kopija^.st) DOstari := tekuci;tekuci := tekuci^.veza

END;kopija^.veza := tekuci;IF tekuci = p THENp := kopija

ELSEstari^.veza := kopija

END;IF (tekuci#NIL) AND (kopija^.st = tekuci^.st) THENkopija^.k := kopija^.k + tekuci^.k;kopija^.veza := tekuci^.veza;DISPOSE(tekuci);IF kopija^.k = 0.0 THENIF p = kopija THENp := kopija^.veza

ELSEstari^.veza := kopija^.veza

END;DISPOSE(kopija)

ENDEND

END

Page 27: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

5.1 Moduli 27

END UbaciMonom;

PROCEDURE Unos(VAR p : Polinom);VARi, n: CARDINAL;novi: Polinom;

BEGINAnuliraj(p);REPEATWriteLn;WriteString(’Unesite broj monoma n (n>=0) ’);ReadCard(n);

UNTIL Done;WriteLn;FOR i := 1 TO n DONEW(novi);WITH novi^ DOREPEATWriteString(’Unesite koeficijent monoma br.’);WriteCard(i, 1);WriteString(’ (<> 0) ’);ReadReal(k);WriteLn

UNTIL k <> 0.0;REPEATWriteLn;WriteString(’Unesite eksponent monoma br.’);WriteCard(i, 1);WriteString(’ (>=0) ’);ReadCard(st);

UNTIL Done;WriteLn;

END;UbaciMonom(novi, p);DISPOSE(novi);

ENDEND Unos;

PROCEDURE Saberi(p1, p2: Polinom; VAR zbir: Polinom);BEGINKopiraj(p1, zbir);WHILE p2 <> NIL DOUbaciMonom(p2, zbir);p2 := p2^.veza

ENDEND Saberi;

PROCEDURE SaberiNa(p: Polinom; VAR rez: Polinom);BEGINWHILE p <> NIL DOUbaciMonom(p,rez);p := p^.veza;

END;END SaberiNa;

PROCEDURE PromeniZnak(VAR p: Polinom);VARt: Polinom;

BEGINt := p;WHILE t <> NIL DOt^.k := - t^.k;t := t^.veza

ENDEND PromeniZnak;

PROCEDURE Oduzmi(p1,p2: Polinom; VAR razlika: Polinom);BEGINKopiraj(p2, razlika);PromeniZnak(razlika);WHILE p1 <> NIL DOUbaciMonom(p1, razlika);p1 := p1^.veza

ENDEND Oduzmi;

Page 28: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

28 Strukture podataka i algoritmi 1 – skripta

PROCEDURE MonomPuta(p, mon: Polinom; VAR mp: Polinom);VARtekuci: Polinom;

BEGINAnuliraj(mp);IF (mon <> NIL) AND (p <> NIL) THENNEW(mp);mp^.k := p^.k * mon^.k;mp^.st := p^.st + mon^.st;p := p^.veza;tekuci := mp;WHILE p <> NIL DONEW(tekuci^.veza);tekuci := tekuci^.veza;tekuci^.k := p^.k * mon^.k;tekuci^.st := p^.st + mon^.st;p := p^.veza

END;tekuci^.veza := NIL

ENDEND MonomPuta;

PROCEDURE Puta(p1, p2: Polinom; VAR pr: Polinom);VARpomocni, brisi: Polinom;

BEGINAnuliraj(pr);IF (p1 <> NIL) AND (p2 <> NIL) THENMonomPuta(p1, p2, pr);p2 := p2^.veza;WHILE p2 <> NIL DOMonomPuta(p1, p2, pomocni);REPEATUbaciMonom(pomocni, pr);brisi := pomocni;pomocni := pomocni^.veza;DISPOSE(brisi);

UNTIL pomocni = NIL;p2 := p2^.veza

ENDEND

END Puta;

PROCEDURE Kolicnik(p1, p2: Polinom; VAR kol, ost: Polinom; VAR ok: BOOLEAN);

PROCEDURE Deli(VAR kol, ost: Polinom);VARnovi, pomocni: Polinom;

BEGINIF ost <> NIL THENIF ost^.st >= p2^.st THENNEW(novi);novi^.k := - ost^.k / p2^.k;novi^.st := ost^.st - p2^.st;MonomPuta(p2, novi, pomocni);SaberiNa(pomocni, ost);DisposePolinom(pomocni);novi^.k := - novi^.k;UbaciMonom(novi, kol);DISPOSE(novi);Deli(kol, ost)

ENDEND

END Deli;

BEGIN (* Kolicnik *)ok := TRUE;Anuliraj(kol);IF p2 = NIL THENok := FALSE

ELSEKopiraj(p1, ost);Deli(kol, ost)

ENDEND Kolicnik;

Page 29: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

5.2 Zadatak: Sabiranje sa unapred određenim polinomom 29

PROCEDURE PolinomNaN(p: Polinom; n: CARDINAL;VAR rez: Polinom);

VARi: CARDINAL;pret : Polinom;

BEGINIF n = 0 THENNEW(rez);rez^.k := 1.0;rez^.st := 0;rez^.veza := NIL;

ELSEKopiraj( p, rez );FOR i := 2 TO n DOpret := rez;Puta(pret, p, rez);DisposePolinom(pret);

ENDEND;

END PolinomNaN;

PROCEDURE DisposePolinom(VAR p: Polinom);VARpomocni: Polinom;

BEGINpomocni := p;WHILE pomocni # NIL DOp := p^.veza;DISPOSE(pomocni);pomocni := p

ENDEND DisposePolinom;

END PolinomL.

5.2 Zadatak: Sabiranje sa unapred određenim polinomomŽelimo da ispišemo uneti polinom uvećan za

x5 − 3x4 + 4x + 7.MODULE polinom;FROM PolinomL IMPORT Polinom, Stampaj, Anuliraj,

DisposePolinom, PostaviClan, Unos, Saberi;FROM InOut IMPORT WriteString, WriteLn;

VARp,q,rez : Polinom;

BEGIN(* korisnik unosi prvi polinom *)WriteString("Unesite polinom:");WriteLn;Unos(p);(* drugi polinom kreiramo mi,

monom po monom *)Anuliraj(q); (* isto sto i q:=NIL; *)(* postavimo clan x^5 *)PostaviClan(1.0,5,q);(* -3 x^4 *)PostaviClan(-3.0,4,q);(* 4 x *)PostaviClan(4.0,1,q);(* 7 (x^0) *)PostaviClan(7.0,0,q);(* saberemo polinome *)Saberi(p, q, rez);(* odstampamo rezultat i polinome *)WriteString("p: ");Stampaj(p,0);WriteLn;WriteString("q: ");Stampaj(q,0);WriteLn;WriteString("rez: ");Stampaj(rez,0);

Page 30: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

30 Strukture podataka i algoritmi 1 – skripta

WriteLn;DisposePolinom(p);DisposePolinom(q);DisposePolinom(rez);

END polinom.

5.3 Zadatak: Suma k polinomaNapisati program koji ucitava broj k (1<=k<=50) i k polinoma, a nakon toga izracunava njihovu

sumuMODULE PolSuma;(* Napisati program koji ucitava broj k (1 <= k <= 50) i k polinoma, a nakon toga

izracunava njihovu sumu *)

FROM PolinomL IMPORT Polinom, Anuliraj, DisposePolinom,Unos, Stampaj, SaberiNa;

FROM InOut IMPORT WriteLn, WriteString, ReadCard, WriteCard;CONSTmaxk = 50;

TYPEnizPol = ARRAY [1..maxk] OF Polinom;

VARi, k: CARDINAL;suma : Polinom;p : nizPol;

BEGINREPEATWriteString(’Unesite broj k (1 <= k <= ’);WriteCard(maxk, 1);WriteString(’) ’);ReadCard(k);WriteLn;

UNTIL (1 <= k) AND (k <= maxk);FOR i := 1 TO k DOWriteLn;WriteString(’Unos ’);WriteCard(i, 1);WriteString(’. polinoma.’);WriteLn;Unos(p[i])

END;Anuliraj(suma);FOR i := 1 TO k DOSaberiNa(p[i], suma)

END;WriteLn;WriteString(’Njihova suma je:’);WriteLn;Stampaj(suma, 4);DisposePolinom(suma);FOR i := 1 TO k DODisposePolinom(p[i]);

END;END PolSuma.

Page 31: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

6 Stek i red opsluživanja 31

6 Stek i red opsluživanja

6.1 Primer: osnovno korišćenje steka i reda opsluživanja

MODULE stekred;(* prvo importujemo cele module, da bi mogli da koristimo istoimeneprocedure (kao MakeNull) iz oba modula *)

IMPORT RedOpsl;IMPORT Stek;(* nakon toga importujemo i sve raznoimene delove, da ne bi morali

da kucamo puna imena modula svaki put i kad ne moramo *)FROM Stek IMPORT StekTip, Top, Pop, Push;FROM RedOpsl IMPORT RedOpslTip, First, PopFirst, AddRear;FROM InOut IMPORT ReadString,WriteString,Write,WriteLn;FROM Strings IMPORT Length;

VARstr : ARRAY[1..256] OF CHAR;q :RedOpslTip;s :StekTip;i : CARDINAL;ok,palin : BOOLEAN;c,c1 : CHAR;

BEGINWriteString("unesite string: ");ReadString(str);

(* inicijalizujemo strukture *)Stek.MakeNull(s);RedOpsl.MakeNull(q);(* ubacujemo elemente u stek *)FOR i:=1 TO Length(str) DO

Push(s, str[i], ok);END;(* ubacujemo elemente u red opsl *)FOR i:=1 TO Length(str) DO

AddRear(q, str[i], ok);END;WriteLn;WriteString("sadrzaj steka");WriteLn;WHILE NOT Stek.Empty(s) DO

Top(s,c,ok);Pop(s,ok);Write(c);

END;WriteLn;WriteString("sadrzaj reda opsl.");WriteLn;WHILE NOT RedOpsl.Empty(q) DO

First(q,c,ok);PopFirst(q,ok);Write(c);

END;WriteLn;

END stekred.

6.2 Zadatak: Ilustracija pisanja u fajl uz pomoć bafera

DEFINITION MODULE QueueInfo;CONSTMaxqueue = 100;

TYPEInfoTip = CHAR;

END QueueInfo.

IMPLEMENTATION MODULE QueueInfo;END QueueInfo.

DEFINITION MODULE RedOpsl1;FROM QueueInfo IMPORT InfoTip,Maxqueue;TYPENiz = ARRAY[1..Maxqueue] OF InfoTip;RedOpslTip = RECORD

Page 32: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

32 Strukture podataka i algoritmi 1 – skripta

Prvi, Zadnji : CARDINAL;Element : Niz

END;

PROCEDURE MakeNull(VAR q : RedOpslTip);PROCEDURE Empty(VAR q : RedOpslTip) : BOOLEAN;PROCEDURE First(VAR q : RedOpslTip;

VAR x : InfoTip;VAR ok : BOOLEAN);

PROCEDURE PopFirst(VAR q : RedOpslTip;VAR ok : BOOLEAN);

PROCEDURE AddRear(VAR q : RedOpslTip;x : InfoTip;VAR ok : BOOLEAN);

END RedOpsl1.

IMPLEMENTATION MODULE RedOpsl1;FROM QueueInfo IMPORT Maxqueue,InfoTip;

PROCEDURE MakeNull(VAR q : RedOpslTip);BEGINWITH q DOPrvi := 0;Zadnji := 0

ENDEND MakeNull;

PROCEDURE Empty(VAR q : RedOpslTip) : BOOLEAN;BEGINRETURN q.Zadnji = 0

END Empty;

PROCEDURE First(VAR q : RedOpslTip;VAR x : InfoTip;VAR ok : BOOLEAN);

BEGINIF Empty(q) THENok := FALSE

ELSEok := TRUE;WITH q DOx := Element[Prvi]

ENDEND

END First;

PROCEDURE AddOne(i : CARDINAL) : CARDINAL;BEGINIF i = Maxqueue THENRETURN 1

ELSERETURN i+1

ENDEND AddOne;

PROCEDURE PopFirst(VAR q : RedOpslTip;VAR ok : BOOLEAN);

BEGINIF Empty(q) THENok := FALSE

ELSEok := TRUE;WITH q DOIF Prvi = Zadnji THENMakeNull(q)

ELSEPrvi := AddOne(Prvi)

ENDEND

ENDEND PopFirst;

PROCEDURE AddRear(VAR q : RedOpslTip;x : InfoTip;

Page 33: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

6.2 Zadatak: Ilustracija pisanja u fajl uz pomoć bafera 33

VAR ok : BOOLEAN);BEGINWITH q DOIF AddOne(Zadnji) = Prvi THENok := FALSE

ELSEok := TRUE;IF Empty(q) THENPrvi := 1;Zadnji := 1

ELSEZadnji := AddOne(Zadnji)

END;Element[Zadnji] := x

ENDEND

END AddRear;

END RedOpsl1.

MODULE Bafer;FROM RedOpsl1 IMPORT RedOpslTip, MakeNull, Empty, First, PopFirst, AddRear;FROM FIO IMPORT File,WrChar, Create, Close;IMPORT IO;

CONSTImeIzlaza = ’izlaz.txt’;

VARizlaz : File;znak : CHAR;buffer : RedOpslTip;

PROCEDURE IsprazniBafer(VAR dat : File;VAR buf : RedOpslTip);

VARznak : CHAR;ok : BOOLEAN;

BEGINWHILE NOT Empty(buf) DOFirst(buf, znak, ok);PopFirst(buf, ok);WrChar(dat, znak)

ENDEND IsprazniBafer;

PROCEDURE BaferWrite(VAR dat : File;VAR buf : RedOpslTip;znak : CHAR);

VARok : BOOLEAN;

BEGINAddRear(buf, znak, ok);IF NOT ok THENIsprazniBafer(dat, buf);AddRear(buf, znak, ok)

ENDEND BaferWrite;

BEGINizlaz := Create(ImeIzlaza);MakeNull(buffer);IO.WrStr(’Unesite tekst, koji treba da se unese u datoteku ’);IO.WrStr(ImeIzlaza);IO.WrChar(’.’);IO.WrLn;IO.WrStr(’Unos zavrsite tackom.’);IO.WrLn;znak := IO.RdChar();WHILE znak # ’.’ DOBaferWrite(izlaz, buffer, znak);znak := IO.RdChar();

END;IsprazniBafer(izlaz, buffer);Close(izlaz)

END Bafer.

Page 34: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

34 Strukture podataka i algoritmi 1 – skripta

6.3 Zadatak: Ispitivanje da li reč pripada gramatici wcw+

Reč pripada ovoj gramatici ako joj se prvi deo (w) sastoji samo od slova ’a’ i ’b’, sledi slovo ’c’ anakon njega obrnuta reč reči w.DEFINITION MODULE Stek;CONSTMaxstack = 100;

TYPENiz = ARRAY [1..Maxstack] OF CHAR;StekTip = RECORD

Top : CARDINAL;Element : Niz

END;PROCEDURE MakeNull(VAR s : StekTip);PROCEDURE Empty(VAR s : StekTip) : BOOLEAN;

PROCEDURE Top(VAR s : StekTip;VAR x : CHAR;VAR ok : BOOLEAN);

PROCEDURE Pop(VAR s : StekTip;VAR ok : BOOLEAN);

PROCEDURE Push(VAR s : StekTip;x : CHAR;VAR ok : BOOLEAN);

END Stek.

IMPLEMENTATION MODULE Stek;

PROCEDURE MakeNull(VAR s : StekTip);BEGINs.Top := 0

END MakeNull;

PROCEDURE Empty(VAR s : StekTip) : BOOLEAN;BEGINRETURN s.Top = 0

END Empty;

PROCEDURE Top(VAR s : StekTip;VAR x : CHAR;VAR ok : BOOLEAN);

BEGINIF Empty(s) THENok := FALSE

ELSEok := TRUE;WITH s DOx := Element[Top]

ENDEND

END Top;

PROCEDURE Pop(VAR s : StekTip;VAR ok : BOOLEAN);

BEGINIF Empty(s) THENok := FALSE

ELSEok := TRUE;DEC(s.Top)

ENDEND Pop;

PROCEDURE Push(VAR s : StekTip;x : CHAR;VAR ok : BOOLEAN);

BEGINWITH s DOIF Top = Maxstack THENok := FALSE

ELSEok := TRUE;INC(Top);Element[Top] := x

END

Page 35: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

6.3 Zadatak: Ispitivanje da li reč pripada gramatici wcw+ 35

ENDEND Push;END Stek.

MODULE wcw;(* Da li rec pripada gramatici wcw+. *)FROM Stek IMPORT StekTip, MakeNull, Empty,

Top, Pop, Push;FROM InOut IMPORT Read, Write, WriteString, EOL;TYPEslova = SET OF CHAR;

VARS : StekTip;Ch, C : CHAR;ok : BOOLEAN;

BEGINMakeNull(S);Read(Ch);ok := TRUE;WHILE ok AND (Ch IN slova{’a’, ’b’}) DOPush(S, Ch, ok);Read(Ch);

END;IF NOT ok THENWriteString(’Greska - mali stek’)

ELSIF Ch # ’c’ THENWriteString(’Pogresan string’)

ELSERead(Ch);WHILE ok AND (Ch # EOL) DOTop(S, C, ok);ok := ok AND (C = Ch);IF ok THENPop(S, ok);Read(Ch);

ENDEND;IF NOT (ok AND Empty(S)) THENWriteString(’Pogresan string’)

ELSEWriteString(’String pripada jeziku L’)

ENDEND

END wcw.

Page 36: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

36 Strukture podataka i algoritmi 1 – skripta

6.4 Zadatak: Kalkulator za izračunavanje postfiksnih izrazaNapraviti kalkulator za izračunavanje postfiksnih izraza. Svi brojevi koji figurišu u izrazu su jedno-

cifreni.MODULE PostFix;

FROM StekI IMPORT StekTip, MakeNull, Empty, Top, Pop, Push;FROM InOut IMPORT Read, Write, WriteInt, EOL;TYPEslova = SET OF CHAR;

VARS : StekTip;Ch : CHAR;Op1, Op2 : INTEGER;ok : BOOLEAN;

PROCEDURE Conv(Ch : CHAR) : INTEGER;BEGINRETURN ORD(Ch) - ORD(’0’)

END Conv;

BEGINMakeNull(S);Read(Ch);WHILE Ch # EOL DOIF Ch IN slova{’+’, ’-’, ’/’, ’*’, ’%’} THENTop(S, Op2, ok);Pop(S, ok);Top(S, Op1, ok);Pop(S, ok);CASE Ch OF’+’ : Op1 := Op1 + Op2 |’-’ : Op1 := Op1 - Op2 |’*’ : Op1 := Op1 * Op2 |’/’ : Op1 := Op1 DIV Op2 |’%’ : Op1 := Op1 MOD Op2

END;Push(S, Op1, ok)

ELSEPush(S, Conv(Ch), ok)

END;Read(Ch);

END;Top(S, Op1, ok);Write(’=’);WriteInt(Op1,5)

END PostFix.

Page 37: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

7 Simulacija rekurzije 37

7 Simulacija rekurzijeNa početku označiti sve rekurzivne pozive u originalnoj proceduri adresama (npr. 1,2,3... ili kon-

stante nabrojivog tipa podataka).Na steku se čuvaju lokalne promenljive, parametri procedure i adresa mesta poziva, a u skladu sa

tim se kreira InfoTip.Trivijalnim pozivom se smatra onaj koji se izračunava bez dodatnih rekurzivnih poziva.U kodu ispod, treba_rekurzija znači da je poziv netrivijalan, odnosno treba naći uslove pod

kojima se sigurno dešavaju rekurzivni pozivi.MakeNull(S);REPEATWHILE treba_rekurzija DO-prepisati sve od pocetka originalneprocedure do prvog rekurzivnog poziva-staviti na stek potrebnelokalne promenljive, parametre procedure iadresu mesta poziva-podesiti vrednosti parametara da budukao u rekurzivnom pozivu procedure

END;trivijalan pozivumesto RETURN x pisati rez := xjos := TRUE;WHILE jos AND NOT Empty(S) DOTop(S, el, ok);Pop(S, ok);-restauriramo vrednosti sa steka-u zavisnosti od adrese poziva nastavimoprepisivanje originalne procedure satog mesta-ako se dodje do novog rek. poziva tada:

-sacuvati na steku vrednosti-podesiti vrednosti parametara da budukao u rekurzivnom pozivu procedure-ici na pocetak koda(ovo se postize sa jos := FALSE)

-inaceako se naidje na RETURN x pisati rez := x

ENDUNTIL Empty(S);

Ako je procedura funkcijska tada se na kraj dodaje RETURN rez.

ZADACISimulirati ponašanje sledećih rekurzivnih procedura (funkcija) upotrebom steka:

7.1 Primer 1 – faktorijel

MODULE Fakto;(* InfoTip = CARDINAL; *)

FROM IO IMPORT WrStr, WrLn, WrCard, RdCard;FROM StekC IMPORT StekTip, MakeNull, Empty,

Top, Pop, Push;VARn : CARDINAL;

PROCEDURE RFakto(n : CARDINAL) : CARDINAL;BEGINIF n <= 1 THENRETURN 1

ELSERETURN n * RFakto(n-1)

ENDEND RFakto;

PROCEDURE SFakto(n : CARDINAL) : CARDINAL;VARs : StekTip;rez : CARDINAL;OK : BOOLEAN;

Page 38: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

38 Strukture podataka i algoritmi 1 – skripta

BEGINMakeNull(s);WHILE n > 1 DOPush(s,n,OK);DEC(n)

END;rez := 1;WHILE NOT Empty(s) DOTop(s, n, OK);Pop(s, OK);rez := n * rez

END;RETURN rez

END SFakto;

BEGINWrStr(’n = ’);n := RdCard();WrLnWrStr(’n! = ’);WrCard(RFakto(n), 1);WrStr(’ = ’);WrCard(SFakto(n), 1)

END Fakto.

7.2 Primer 2 – stepenovanje

MODULE Step;(* InfoTip = RECORD

x : REAL;n : CARDINAL;adr : (par, nepar)

END;*)FROM IO IMPORT WrStr, WrLn, WrReal,

RdReal, RdCard;FROM StekStep IMPORT StekTip, MakeNull, Empty,

Top, Pop, Push, InfoTip, AdrTip;VARn : CARDINAL;x : REAL;

PROCEDURE Sqr(y : REAL) : REAL;BEGINRETURN y * y

END Sqr;

PROCEDURE RStep(x : REAL;n : CARDINAL) : REAL;

BEGINIF n = 0 THENRETURN 1.

ELSIF ODD(n) THENRETURN x * Sqr( RStep(x, n DIV 2) )

ELSERETURN Sqr( RStep(x, n DIV 2) )

ENDEND RStep;

PROCEDURE SStep(x : REAL;n : CARDINAL ) : REAL;

VARs : StekTip;OK : BOOLEAN;rez : REAL;el : InfoTip;

BEGINMakeNull(s);WHILE n > 0 DOel.x := x;el.n := n;IF ODD(n) THENel.adr := nepar;

ELSEel.adr := par

END;

Page 39: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

7.3 Primer 3 – Fibonači 39

Push(s,el,OK);n := n DIV 2

END;rez := 1.;WHILE NOT Empty(s) DOTop(s, el, OK);Pop(s, OK);x := el.x;n := el.n;IF el.adr = nepar THENrez := x * Sqr(rez)

ELSErez := Sqr(rez)

ENDEND;RETURN rez

END SStep;

BEGINWrStr(’x =? ’);x := RdReal();WrLn;WrStr(’n =? ’);n := RdCard();WrStr(’x^n = ’);WrReal(RStep(x, n), 10, 1);WrStr(’ = ’);WrReal(SStep(x, n), 10, 1)

END Step.

7.3 Primer 3 – Fibonači

MODULE Fib;(* InfoTip = RECORD

n : CARDINAL;PrviSab : CARDINAL;adr : (prvi, drugi)

END;*)

FROM IO IMPORT WrStr, WrLn, WrCard, RdCard;FROM StekFib IMPORT StekTip, MakeNull, Empty,

Top, Pop, Push, InfoTip, AdrTip;VARn : CARDINAL;

PROCEDURE RFib(n : CARDINAL) : CARDINAL;BEGINIF n <= 1 THENRETURN n

ELSERETURN RFib(n-1) + RFib(n-2)

ENDEND RFib;

PROCEDURE SFib(n : CARDINAL ) : CARDINAL;VARs : StekTip;OK, jos : BOOLEAN;rez, PrviSab : CARDINAL;el : InfoTip;

BEGINMakeNull(s);REPEATWHILE n > 1 DOel.n := n;el.adr := prvi;Push(s,el,OK);DEC(n)

END;rez := (n);jos := TRUE;WHILE (NOT Empty(s)) AND jos DOTop(s, el, OK);Pop(s, OK);n := el.n;

Page 40: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

40 Strukture podataka i algoritmi 1 – skripta

IF el.adr = prvi THENPrviSab := rez;el.n := n;el.adr := drugi;el.PrviSab := PrviSab;Push(s, el, OK);DEC(n, 2);jos := FALSE

ELSEPrviSab := el.PrviSab;rez := PrviSab + rez

ENDEND

UNTIL Empty(s);RETURN rez

END SFib;

BEGINWrStr(’n =? ’);n := RdCard();WrStr(’F(n) = ’);WrCard(RFib(n), 1);WrStr(’ = ’);WrCard(SFib(n), 1)

END Fib.

7.4 Primer 4 – faktorijel 2

MODULE Faktor;(* InfoTip = CARDINAL; *)FROM IO IMPORT WrStr, WrLn, WrCard, RdCard;FROM StekC IMPORT StekTip, MakeNull, Empty,

Top, Pop, Push;VARn,rez : CARDINAL;

PROCEDURE RFakto(n : CARDINAL;VAR rez : CARDINAL);

BEGINIF n = 0 THENrez := 1

ELSERFakto(n-1, rez);rez := n * rez

ENDEND RFakto;

PROCEDURE SFakto(n : CARDINAL;VAR rez : CARDINAL);

VARs : StekTip;OK : BOOLEAN;

BEGINMakeNull(s);WHILE n > 0 DOPush(s,n,OK);DEC(n)

END;rez := 1;WHILE NOT Empty(s) DOTop(s, n, OK);Pop(s, OK);rez := n * rez

ENDEND SFakto;

BEGINWrStr(’n =? ’);n := RdCard();WrLn;WrStr(’n! = ’);RFakto(n, rez);WrCard(rez, 1);WrStr(’ = ’);SFakto(n, rez);WrCard(rez, 1)

Page 41: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

7.5 Primer 5 (ispitni) 41

END Faktor.

7.5 Primer 5 (ispitni)

MODULE Rek1;(* InfoTip = RECORD

d, g, m1, m2 : INTEGER;adr : (prvi, drugi)

END;*)FROM Stek1 IMPORT StekTip, adresa, InfoTip,

MakeNull, Empty, Top, Pop, Push;IMPORT IO;VARX : ARRAY [1..20] OF INTEGER;

PROCEDURE Max(d, g: INTEGER) : INTEGER;VARm1, m2 : INTEGER;

BEGINIF d>g THENRETURN MIN(INTEGER)

ELSIF d=g THENRETURN X[d]

ELSEm1 := Max(d, (d+g) DIV 2);m2 := Max((d+g) DIV 2 +1, g);IF m1 > m2 THENRETURN m1

ELSERETURN m2

ENDEND

END Max;

PROCEDURE SMax(d, g: INTEGER) : INTEGER;VARS : StekTip;el : InfoTip;ok, jos : BOOLEAN;m1, m2, rez : INTEGER;

BEGINMakeNull(S);REPEATWHILE d<g DOel.d := d;el.g := g;el.adr := prvi;Push(S, el, ok);g := (d+g) DIV 2

END;IF d>g THENrez := MIN(INTEGER)

ELSE (* d=g *)rez := X[d]

END;jos := TRUE;WHILE jos AND NOT Empty(S) DOTop(S, el, ok);Pop(S, ok);d := el.d;g := el.g;m1 := el.m1;IF el.adr = prvi THENm1 := rez;el.m1 := m1;el.adr := drugi;Push(S, el, ok);d := (d+g) DIV 2 + 1;jos := FALSE

ELSE (*el.adr = drugi*)m2 := rez;IF m1 > m2 THENrez := m1

ELSErez := m2

Page 42: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

42 Strukture podataka i algoritmi 1 – skripta

ENDEND

ENDUNTIL Empty(S);RETURN rez

END SMax;

BEGIN (* glavni program *)X[1] := 3;X[2] := 2;X[3] := 5;X[4] := -7;X[5] := 0;IO.WrCard(Max(1, 5), 3);IO.WrLn;IO.WrCard(SMax(1, 5), 3);IO.WrLn

END Rek1.

7.6 Primer 6 (ispitni)

MODULE Rek2;(* InfoTip = RECORD

x, y, n : CARDINAL;adr : (prvi, drugi, treci, cetvrti)

END;*)FROM Stek2 IMPORT StekTip, adresa, InfoTip,

MakeNull, Empty, Top, Pop, Push;IMPORT IO;

PROCEDURE g(x : CARDINAL; y : CARDINAL;n : CARDINAL) : CARDINAL;

BEGINIF n < 3 THENRETURN x + y

ELSIF ODD(n) THENRETURN g(g(x+1, y, n-2), y, n-3)

ELSERETURN g(x, g(x, y+1, n-2), n-3)

ENDEND g;

PROCEDURE Sg(x : CARDINAL; y : CARDINAL;n : CARDINAL) : CARDINAL;

VARS : StekTip;el : InfoTip;ok, jos : BOOLEAN;rez : CARDINAL;

BEGINMakeNull(S);REPEATWHILE n >= 3 DOIF ODD(n) THENel.x := x;el.y := y;el.n := n;el.adr := prvi;Push(S, el, ok);INC(x);DEC(n, 2)

ELSEel.x := x;el.y := y;el.n := n;el.adr := treci;Push(S, el, ok);INC(y);DEC(n, 2)

ENDEND;rez := x+y;jos := TRUE;WHILE jos AND NOT Empty(S) DOTop(S, el, ok);

Page 43: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

7.6 Primer 6 (ispitni) 43

Pop(S, ok);x := el.x;y := el.y;n := el.n;IF el.adr = prvi THENel.adr := drugi;Push(S, el, ok);x := rez;DEC(n, 3);jos := FALSE

ELSIF el.adr = treci THENel.adr := cetvrti;Push(S, el, ok);y := rez;DEC(n, 3);jos := FALSE

ENDEND

UNTIL Empty(S);RETURN rez

END Sg;

BEGIN (* glavni program *)IO.WrCard(g(2, 3, 10), 3);IO.WrCard(Sg(2, 3, 10), 3);

END Rek2.

Page 44: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

A Native XDS Modula 2 – kratko uputstvo I

A Native XDS Modula 2 – kratko uputstvoOvo uputstvo ukratko pokriva kako se može nabaviti XDS Modula 2 za Windows sistem, njenu

instalaciju, te kako napraviti i pokretnuti jednostavan program.

Dobavljanje instalacijeNative XDS Modula 2 se može besplatno skinuti sa sajta proizvođača, tačnije na adresi:

http://www.excelsior-usa.com/xdsdl.htmlPrvo se prikazuje ugovor o korišćenju koji na dnu treba potvrditi da ste razumeli i da ćete ga se

pridržavati.Na stranici koja se potom otvara je potrebno odabrati “XDS 2.6 beta 2 for Windows” i snimiti je

na računar.

Instalacija okruženjaOsnovno okruženje (xds-x86...) se instalira pokretanjem prethodno pomenute instalacione arhive.Korisnicima Windows-a 7 preporučujemo da pokrenu instalacione pakete pomoću opcije “Run as

administrator” do koje se stiže desnim klikom miša.Pretpostavićemo u daljem tekstu da je program instaliran u C:/XDS/

Pokretanje okruženjaPo uspešnoj instalaciji bi trebalo da postoji ikonica na desktopu, kao i grupa sa programom u start

meniju.Ukoliko iz bilo kakvog razloga ne postoje odgovarajuće prečice, okruženje se može pokrenuti uz

pomoć izvršnog fajla C:/XDS/BIN/xds.exe (ako je instalirano na podrazumevanoj lokaciji).

Prvi projekatDa bismo mogli da pišemo i pokrećemo svoj program, potrebno je prvo napraviti projekat za njega,

što se radi na sledeći način:

• Iz menija se odabere Project->New.• U dijalogu se klikne na gornje dugme “Browse”, odabere se putanja gde će se kreirati projekat iukuca se ime novog projekta.

• U drugom polju “Template” ne treba da piše ništa. Ukoliko postoji neki tekst, obrisati ga.• Kliknuti na “OK”• Iskočiće dijalog na kome piše da ne postoji fajl za editovanje, kliknuti na “OK” da se on napravi.• Pojavljuje se forma za kucanje programa, ukucati (na primer):

MODULE Hello;FROM InOut IMPORT WriteString,WriteLn;BEGINWriteString("Hello World");WriteLn;

END Hello.

• Program se može pokrenuti na različite načine, pri čemu se automatski prevodi:

– Klik na “Run” ikonicu u toolbaru (plavi čovečuljak koji trči)– Meni Debug->Run– Prečica Ctrl+F9 na tastaturi

• Ako je sve u redu sa programom, treba da se pojavi novi terminal u kome se ispisuje rezultatizvršavanja programa, u našem slučaju jednostavna pozdravna poruka.

Naravno moguće je i samo prevesti (kompajlirati) program, tako da se samo prikažu greške (ako ihima) i bez pokretanja programa:

• Klik na “Compile” ikonicu u toolbaru• Meni Tools->Compile• Prečica F9 na tastaturi

Page 45: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

II Strukture podataka i algoritmi 1 – skripta

Ukoliko u programu postoje greške, on neće biti pokrenut, već će se dobiti lista grešaka u donjemdelu prozora. Na primer ako obrišemo “S” u četvrtom redu i probamo da pokrenemo program, taj redće biti označen svetlo plavom bojom i dobićemo poruku:

- Error in pro1.mod [4:5]: Undeclared identifier "Writeting"Što znači da u četvrtom redu, kod petog karatkera postoji problem, da identifikator nije deklarisan,

što najčešće znači da ga nismo uvezli, ili, kao u našem slučaju, da smo napravili grešku u kucanju.Stvar na koju isto treba obratiti pažnju je da se nekad greška prijavljue nešto kasnije u tekstu

nego što je napravljena. Na primer, ako obrišemo “;” na kraju četvrtog reda i probamo da pokrenemoprogram, peti red će biti označen svetlo plavom bojom i dobićemo poruku:

- Error in pro1.mod [5:5]: Expected symbol ";"Ovo se desilo jer nedostaje tačka zarez na kraju četvrtog reda, ali će kompajler probati da je traži i

dalje, pa će tek na početku petog reda prijaviti grešku.U spisku se takođe pojavljuje i upozorenje (Warning) o tome da se uvezena komanda WriteString

ne koristi nigde u programu. Često se upozorenja mogu ignorisati, a pažnju uglavnom treba obraćatina greške, odnosno poruke koje počinju sa “Error”.

Takođe se često dešava da su druge prijavljene greške posledica prve, te je poželjno ponovo kom-pajlirati (ili pokretati) program posle svake ispravljene greške.

Napomena o template-ovima pri kreiranju projekta: Moguće je namestiti da u dijalogu za noviprojekat drugo polje “Template” uvek bude prazno. Potrebno je u tom istom dijalogu kliknuti na“Configure”, a potom isprazniti polje “default template”.

A.1 Mogući problemiNedostajući sistemski moduli

Verzije pre 2.6 nisu imale uključene u glavni paket sve module koji se koriste u okviru kursa, i biloje neophodno da se dodatno instalira i “Top Speed Compatibility Pack” (tscp-x86...). Bez njega jekompajler prijavljivao da ne postoje neki moduli - najčešće je problem bio da nedostaje FIO modul.

Problemi u pokretanju - nemoguće naći exe

Ako pri pokušaju kompajliranja/pokretanja programa kompajler prijavi da ne može da nađe exei pri tome prijavljuje kraću putanju od one koja je stvarno u pitanju, obično se radi o tome da jepostojao razmak u okviru putanje do modula. Npr “C:\Moj prvi program” će prouzrokovati probleme,a kompajler će prijaviti da ne može da nađe “C:\Moj”.

Ovo je nažalost problem okruženja i dok se ne ispravi u nekoj budućoj verziji ne može se zaobići,tako da je jedino rešenje premestiti fajlove, odnosno ako je moguće preimenovati problematične foldere.

Page 46: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

B XDS modula 2 - rad iz komandne linije III

B XDS modula 2 - rad iz komandne linijeOvo uputstvu ukratko pokriva kako se XDS kompajler može podesiti da se koristi iz komandne linije,

na Windows, ali i *nix sistemima.Predpostavlja se da je XDS Modula 2 već instalirana (konsultovati odvojeno uputstvo ako nije).

Takođe će se predpostavljati da je instalirana na podrazumevanu lokaciju “c:/xds/”. Ako to nije slučaj,potrebno je zameniti putanje iz upustva sa stvarnom putanjom.

B.1 Prednosti (ili “Zašto ovo raditi?”)Skoro svaki jezik se može kompajlirati iz komandne linije, i onda se rad sa različitim jezicima svodi

na rad u svom omiljenom editoru teksta (npr Notepad++, jEdit, joe, emacs...), koji je prilagođensopstvenim zahtevima i pozivanjem odgovarajućeg kompajlera iz komandne linije.

U konkretnom slučaju XDS kompajlera, ovim se takođe oslobađa potrebe kreiranja projekata kojisu neophodni kad se koristi XDS windows okruženje - bilo koji pojedinačni modul se može direktnokompajlirati, fajlovi se mogu premeštati po folderima, menjati imena foldera i tako dalje.

Još jedna prednost za studente PMF-a koji polažu ispite u okruženju Svetovid je što u njemu dobijajupotpuno iste poruke od kompajlera kao što se dobijaju izvršavanjem kompajliranja iz komandne linije.

B.2 Podešavanje sistemske putanje (ili "OK, odakle početi?")Da bi kompajler mogao da se poziva iz bilo kog foldera na računaru, a ne samo iz “C:/xds/bin”,

potrebno je dodati folder kompajlera u sistemsku putanju (tj spisak foldera koji se pretražuju kadakorisnik pokuša da pokrene neku komandu). Na Windows sistemima se ova promenljiva naziva “PATH”,a trenutnom sadržaju se može pristupiti preko %PATH%.

Putanja se može dodati privremeno komandom:path = %PATH%;c:/xds/bin

ovim se proširuje spisak putanja u trenutom komandom prozoru, odnosno važiće samo u trenutnootvorenom cmd promptu i to dok se isti ne zatvori.

Putanja se može i trajno dodati na nekoliko načina. Na win xp, Vista i 7 sistemima se to može uraditina sledeći način: otvori se “computer properties” (desni klik na "My Computer"), odabere se jezičak"advanced", klikne na dugme "Environment variables", u prozoru koji se otvori odabere se “PATH” iklikne na dugme "edit", nakon čega se na postojeću vrednost doda “c:\xds\bin”. Bitno je da se neobriše postojeća vrednost, kao i da se novi dodatak odvoji sa “;” od postojećih.

B.3 Kompajliranje programaNakon što je podešena sistemska putanja, kompajleru se pristupa komandom "xc". Poziv bez

parametara će dati ispis mogućnosti. Tipična upotreba za kreiranje izvršne verzije programa sadržanuu fajlu "ime.MOD":xc =make =all ime

Ovim pozivom će se rekompajlirati i svi ostali potrebni moduli koji se koriste u okviru programa.Ako postoje greške u programu izvršna verzija neće biti kreirana. Ako već postoji exe napravljen

nekim prethodnim kompajliranjem, on NEĆE biti obrisan.Kompajler greške prijavljuje u sledećem formatu:

* [zad.mod 125.12 E020] * undeclared identifier "RStr" IO.$RStr(ime);

Odnosno ime fajla, red greške i kolona razdvojeni tačkom i kod greške koji počinje sa “E”. Sam kodgreške nije previše bitan, pošto u sledećem redu sledi objašnjenje. Ono što jeste bitno je da se u istomformatu prikazuju i upozorenja kompajlera čiji kodovi počinu sa “W” i po ovome se najlakše razlikuju.

Takođe treba obratiti pažnju na to da nakon objašnjenja greške sledi i ispis samog reda u kome jegreška u koji je dodatno ubačen karakter “$” koji označava tačno nesto greške. Ako se on nalazi napočetku reda često je u pitanju greška iz prethodnog reda (npr nedostaje “;”). Konkretna prikazanagreška je pogrešno napisano “RdStr”.

B.4 Linux i drugi slobodni sistemi (ili "Who needs windows anyway?")Korisnici Linux (i srodnih) sistema takođe mogu koristiti XDS Modulu 2, i to i okruženje i kompajler

iz komandne linije.

Page 47: Skripta za vezbe iz predmeta "Strukture podataka i algoritmi 1"– ver

IV Strukture podataka i algoritmi 1 – skripta

Prvo rešenje je korišćenje Linux verzije XDS kompajlera. Međutim ona se ponaša malo drugačije,nema vizuelno okruženje i, što je najznačajnije za studente PMFa, nema Top Speed Compatibility Packkoji se koristi na vežbama.

Ono što je najbolje rešenje u ovoj situaciji je koriščenje sloja za emuliranje Windowsa - "Wine".Potrebno je pokrenuti instalaciju XDS paketa, isto kao i pod windowsom (ili alternativno preuziti

strukturu foldera iz windowsa i prekopirati u Wine-ov “C” disk).Ovako instaliran XDS se može koristiti i kao normalno programsko okruženje koje se koristi pod

Windowsom.Ono što je inače bila poenta ovog uputsva u celini je bilo korišćenje iz komandne linije.Da bi kompajler radio u bilo kom folderu, potrebno je namestiti PATH pod Wine-om. Treba obratiti

pažnju da to NIJE ista PATH variabla kao ona od Linux sistema. Ovo se može uraditi na sledeći način1:

• Otvori se regedit pod wine-om (wine regedit)• nađe se ključ HKEY_CURRENT_USER/Environment• promeni se polje “path” tako da uključuje i xds bin folder. obratiti pažnju da je potrebno ubacitidodatni "\", pa će krajnja vrednost izgledati ovako nekako:c:\\windows;c:\\windows\\system;c:\\xds\\bin

Nakon ovoga se u bilo kom folderu može vršiti pozivwine xc =make =all zad

predpostavljajući naravno da u folderu postoji “zad.mod” i da je u pitanju ispravan programskimodul, biće kreiran “zad.exe” koji se onda može pokrenuti sawine zad

Jednostavni programi koji rade sa tekstualnim ulazom i izlazom će najčešće raditi bez problema.U zavisnosti od verzija programa nekad se dešava da kada ovako pokrenut program čeka na unos satastature pravi veliko zauzeće procesora.

Postoji i opcija da se otvori novi terminal prozor koji vrši kompletnu emulaciju komandnog promtaoperativnog sistema DOS 6. Npr:wineconsole zad

Ovako pokrenut program će se ponašati identično kao na Windowsu i neće nepotrebno povećavatizauzeće procesora. Međutim odmah nakon završetka rada pokrenute komande (tj programa zad uprimeru) novi prozor će se zatvoriti, što je problem ako je trebalo pročitati izlaz programa. Rešenje zaovo je otvaranje terminala u kome se izvrašava cmd, tj klasični dos promt:wineconsole cmd

U ovako otvorenom promtu se mogu naravno izvršavati sve komande, iako će interakcija biti neštodrugačija od naviknute u modernim konzolama (tipa ispisivanja čudnih kodova umesto kretanja okolokad se pritiskaju strelice).

1Link: uputstvo za sistemske promenljive na zvaničnom sajtu softvera Wine:http://www.winehq.org/docs/wineusr-guide/environment-variables