410 likes | 601 Views
Objektovo- Orientované Programovanie. Naše prvé objekty a ich vlastnosti Zásobník Aritmetický výraz Rad. Vlastnosti objektov:. enkapsulácia (encapsulation - zapúzdrenie) nový dátový typ trieda (class) spojenie typu record a procedúry/funkcie pre manipuláciu so stavovými premennými
E N D
Objektovo- Orientované Programovanie Naše prvé objekty a ich vlastnosti Zásobník Aritmetický výraz Rad
Vlastnosti objektov: enkapsulácia (encapsulation - zapúzdrenie) • nový dátový typ trieda (class) • spojenie typu record a procedúry/funkcie pre manipuláciu so stavovými premennými dedičnosť (inheritance) • od definovaného objektu môžeme odvodiť celú hierarchiu objektov, t.j. potomkov, ktorí dedia prístup k dátovým aj programovým zložkám polymorfizmus • zdieľanie akcií v hierarchii objektov • budeme sa učiť až neskôr
Súbory projektu: • .DPR - textový pascalovský súbor popisuje z čoho sa skladá projekt • .DFM - môže byť textový (závisí od nastavení Delphi) - popisuje formulár • .PAS - pascalovský program Pri uložení projektu a neskôr aj po spúšťaní aplikácie sa často budú automaticky vytvárať aj súbory s inými príponami: • .RES - tento súbor, ak chýba, tak sa vytvorí automaticky, obsahuje len ikonu aplikácie • .CFG - (textový súbor) nastavenia kompilátora (Options)
Súbory projektu: .DSK - (textový súbor) informácie o Delphi prostredí (o oknách) .DOF - (textový súbor) nastavenia kompilátora .DCU - preložená programová jednotka .EXE - spustiteľný program Pozor! - pri prenášaní projektu do iného adresára alebo na iný disk nekopírujte súbory s príponou .DSK - prakticky vám stačí preniesť .DPR, .DFM, .PAS, prípadne .RES, všetko ostatné sa vytvára kompilátorom, pričom prenesený .DSK môže narobiť veľké problémy
Zásobník (Stack)- údajová štruktúra • je pri programovaní veľmi často používaná a pritom je dosť jednoduchá • je to údajová štruktúra, ktorá sa podobá postupnosti prvkov, len spôsob pridávania a odoberania prvkov je špecifický: prvky do štruktúry môžeme pridávať a zo štruktúry odoberať len z jedného konca
Zásobník (Stack)- údajová štruktúra • zásobníku niekedy hovoríme aj LIFO (Last In - First Out) alebo aj nespravodlivý
OOP - Zásobník • Vkladanie prvkov - operácia PUSH • Výber prvkov - operácia POP • Vrchný prvok - operácia TOP • Test na prázdnosť zásobníka - operácia EMPTY • Test na plnosť zásobníka - operácia FULL Urobíme reprezentáciu zásobníka pomocou poľa, t. j. budeme mať pole a budeme sledovať vrchol zásobníka; definujeme const maxStack = 100;
OOP - Zásobník type TPrvok = string; TStack = class st: array[1..maxStack] of TPrvok; vrch: 0..maxstack; constructor Create; procedure push(p: TPrvok); procedure pop(var p: TPrvok); function top: TPrvok; function full: boolean; function empty: boolean; end;
OOP -Zásobník - implementácia uses Dialogs; // obsahuje ShowMessage procedure chyba(s:string); begin ShowMessage(s); halt; // okno so správou end; constructor TStack.Create; begin vrch:=0; end;
OOP -Zásobník - implementácia procedure TStack.push(p:TPrvok); begin if full then chyba('Plný zásobník'); inc(vrch); st[vrch]:=p; end; procedure TStack.pop(var p:TPrvok); begin if empty then chyba('Prázdny zásob.'); p:=st[vrch]; dec(vrch); end;
OOP -Zásobník - implementácia function TStack.top:TPrvok; begin if empty then chyba('Prázdny zásobník'); Result:=st[vrch]; end; function TStack.full:boolean; begin Result:=vrch=maxStack; end;
OOP -Zásobník - implementácia function TStack.empty:boolean; begin Result:=vrch=0; end;
OOP -Zásobník - použitie procedure TForm1.Button1OnClick(Sender: TObject); var t1,t2:TextFile; z:TStack; s:string; begin AssignFile(t1,'unit1.txt'); Reset(t1); AssignFile(t2,'x.txt'); Rewrite(t2); z:=TStack.Create;
OOP -Zásobník - použitie while not eof(t1) do begin readln(t1,s); z.push(s); end; while not z.empty do begin z.pop(s); writeln(t2,s); Memo1.lines.Append(s); end; z.Free; CloseFile(t1); CloseFile(t2); end;
OOP -Zásobník - použitie, projekt program Project1; uses Forms, Unit1 in 'Unit1.pas', StackUnit in 'StackUnit.pas'; {$R *.RES} begin Application.Initialize; Application.CreateForm(TForm1,Form1); Application.Run; end.
Dynamické polia • Sú to polia, ktoré nemajú vopred stanovenú veľkosť, t. j. počet prvkov • deklarujeme ich takto pp: array of typ_prvku • veľkosť poľa musíme zadefinovať pomocou procedúry SetLength(pp, počet_prvkov) procedúra vyhradí pamäť pp:= nil; znamená, že pole je prázdne, má nulový počet prvkov
Dynamické polia • pp:= copy (iné_pole, od_prvku, počet); • štandardná funkcia Length vracia momentálnu veľkosť poľa (pre nil je to 0) • takto definované pole má indexy vždy od 0 po Length(pole)-1, t.j. Low(pp) je 0 a High(pp) je Length(pp)-1
Dynamické polia • ak už pole obsahuje nejaké prvky a meníme jeho veľkosť pomocou SetLength, buď nejaké prvky stratíme, alebo pri zväčšovaní dĺžky pribudnú na koniec nové prvky - zatiaľ ešte s nedefinovanou hodnotou
Dynamické polia - zásobník type TPrvok = string; TStack = class st: array of TPrvok; constructor Create; procedure push(const p:TPrvok); procedure pop(var p:TPrvok); function top:TPrvok; function empty:boolean; end;
Dynamické polia - zásobník uses Dialogs; procedure chyba(const s:string); begin ShowMessage(s); halt; end; constructor TStack.Create; begin st:=nil; end;
Dynamické polia - zásobník procedure TStack.push(const p:TPrvok); begin SetLength(st,Length(st)+1); st[High(st)]:=p; end; procedure TStack.pop(var p:TPrvok); begin if empty then chyba('Prázdny zásobník'); p:=st[High(st)]; SetLength(st,Length(st)-1); end;
Dynamické polia - zásobník function TStack.top:TPrvok; begin if empty then chyba('Prázdny zásobník'); Result:=st[High(st)]; end; function TStack.empty:boolean; begin Result:=Length(st)=0;// alebo Result:= st=nil; end;
Použitie zásobníka • aj veľmi zložitá rekurzívna procedúra sa dá prepísať do nerekurzívneho tvaru pomocou zásobníka • zásobník použijeme aj na spracovanie rôznych typov aritmetických výrazov - zapísaných v infixovom, prefixovom a postixovom tvare
rekurzívna procedúra, ktorá počíta N-té Fibonacciho číslo: var ff:integer; // globálna premenná, v ktorej je vypočítaná hodnota procedure fib(n:integer); var f:integer; begin //časť 1: if n<2 then ff:=1 else begin fib(n-1); //časť 2: f:=ff; fib(n-2); //časť 3: ff:=ff+f; end; end;
nerekurzívny tvar predchádzajúcej procedúry (TPrvok v TStack je už teraz iného typu): procedure fibN(n:integer); var f,v:integer; z:TStack; begin z:=TStack.Create; z.push(1,n,f); while not z.empty do begin z.pop(v,n,f);
case v of 1:if n<2 then ff:=1 else begin z.push(2,n,f) // návrat z.push(1,n-1,f); // rekurzívne volanie end; 2: begin f:=ff; z.push(3,n,f); // návrat z.push(1,n-2,f); // fib(n-2) end; 3: ff:=ff+f; end; end; z.Free; end;
Aritmetické výrazy program na vyhodnotenie postfixu načítaného zo vstupu: ... uses StackUnit; // type TPrvok = integer; ... procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char); var z:TStack; x,y,i:integer; s:string;
Aritmetické výrazy begin if Key<>#13 then exit; z:=TStack.Create; s:=Edit1.Text; Edit1.Text:=''; i:=1; while i<=Length(s) do begin case s[i] of '0'..'9': begin x:=0; while s[i] in ['0'..'9'] do begin x:=x*10+ord(s[i])-ord('0'); inc(i); end; z.push(x); dec(i); end;
Aritmetické výrazy '_': begin z.pop(x); z.push(-x) end; // unárne mínus '+': begin z.pop(x); z.pop(y); z.push(y+x) end; '-': begin z.pop(x); z.pop(y); z.push(y-x) end; '*': begin z.pop(x); z.pop(y); z.push(y*x) end; '/': begin z.pop(x); z.pop(y); z.push(y div x) end; end; inc(i) end; z.pop(x); z.Free; Memo1.Lines.Add(s+' ='+IntToStr(x)); end;
RAD - QUEUE, FRONT, FIFO • dátová štruktúra, postupnosť položiek zoradených za sebou, • ak príde nová položka, pridá sa na koniec radu (rear, tail, chvost) • vyberať položky zo začiatku radu (front, head, hlavička)
RAD - QUEUE, FRONT, FIFO • metódy: • serve = obslúž • append = pridaj na koniec QueueUnit.pas: unit QueueUnit; interface
RAD - QUEUE, FRONT, FIFO type TQPrvok = string; TQueue = class q:array of TQPrvok; constructor Create; procedure serve(var p:TQPrvok; procedure append(p:TQPrvok); function empty:boolean; end;
RAD - QUEUE, FRONT, FIFO implementation uses Dialogs; procedure chyba(const s:string); begin ShowMessage(s); halt; end; constructor TQueue.Create; begin q:=nil; end;
RAD - QUEUE, FRONT, FIFO procedure TQueue.serve(var p:TQPrvok); begin if empty then chyba('Rad je prazdny'); p:=q[0]; q:=copy(q,1,maxint); end;
RAD - QUEUE, FRONT, FIFO procedure TQueue.append(p:TQPrvok); begin SetLength(q,Length(q)+1); q[High(q)]:=p; end; function TQueue.empty:boolean; begin Result:=q=nil; end; end.
RAD - QUEUE, FRONT, FIFO Napíšeme program, ktorý číta textový súbor iba raz a vytvára nový súbor tak, že v tomto súbore sú všetky riadky vstupného súboru a za nimi ešte raz tie isté riadky ... uses QueueUnit; ...
RAD - QUEUE, FRONT, FIFO procedure TForm1.Button1Click(Sender: TObject); var q:TQueue; f,g:TextFile; t:TQPrvok; begin q:=TQueue.Create; AssignFile(f,'Unit1.pas'); Reset(f);
RAD - QUEUE, FRONT, FIFO AssignFile(g,'test.pas'); Rewrite(g); while not eof(f) do begin readln(f,t); q.append(t); writeln(g,t); end; while not q.empty do begin q.serve(t); writeln(g,t) end;
RAD - QUEUE, FRONT, FIFO CloseFile(g); CloseFile(f); q.Free; Memo1.Lines.Add('hotovo'); end;