Dziedziczenie (cd.)

19
22 listopada 200 0 Regula konkatenacji II 1 Dziedziczenie (cd.) • Reguła konkatenacji II • przykład - heapsort • Reguła konkatenacji III

description

Dziedziczenie (cd.). Reguła konkatenacji II przykład - heapsort Reguła konkatenacji III. Reguła konkatenacji II - inner. - PowerPoint PPT Presentation

Transcript of Dziedziczenie (cd.)

Page 1: Dziedziczenie   (cd.)

22 listopada 2000 Regula konkatenacji II 1

Dziedziczenie (cd.)

• Reguła konkatenacji II

• przykład - heapsort

• Reguła konkatenacji III

Page 2: Dziedziczenie   (cd.)

22 listopada 2000 Regula konkatenacji II 2

Reguła konkatenacji II - inner

• Prawda o dziedziczeniu jest bardziej skomplikowana niż mogłoby to wyglądać po poprzednim wykładzie. Rozpatrzmy znany już nam przykład z klasami: rachunek, rachunek_za_elektryczność, …Spróbujmy wydrukować rachunek podczas jego tworzenia

Page 3: Dziedziczenie   (cd.)

22 listopada 2000 Regula konkatenacji II 3

unit bill: class(who: person, day: date);

   var amount: integer, is_paid: Boolean; 

begin writeln(«Rachunek z dnia», day);

writeln(«Dla Pani/Pana», who);

writeln(«kwota do zapłacenia=», amount)

end bill;

a teraz klasa rachunek_za_elektryczność.

unit electricity_bill: bill class(kWh: integer);

begin

    amount := kWh * price_kWh;

end electricity_bill;

i klasa rachunek_za_gaz unit gaz_bill: bill class(cubicmeters: integer);

begin

    amount := cubicmeters * price_gaz;

end gaz_bill;

Jak wydrukować niezerową kwotę?

Jak uniknąć powtarzania trzeciej instrukcji writeln w podklasach?

Page 4: Dziedziczenie   (cd.)

22 listopada 2000 Regula konkatenacji II 4

• Osiągniemy to stosując pseudoinstrukcję inner.

• To słowo kluczowe może wystąpić w klasie dziedziczonej wszędzie tam, gdzie możemy napisać instrukcję.

• Podczas dziedziczenia-składania modułów słowo inner będzie zastąpione instrukcjami klasy dziedziczonej.

• Inner występuje tylko raz w module klasy, domyślnie na końcu ciągu instrukcji.

Page 5: Dziedziczenie   (cd.)

22 listopada 2000 Regula konkatenacji II 5

Reguła konkatenacji II

• Poniższa tabelka prezentuje ideę użycia pseudoinstrukcji inner.

• Należy pamiętać, że słowo inner nie musi- dzielić ciągu instrukcji na prolog i epilog (chociaż jest tak często używane),- może wystąpić wewnątrz instrukcji while lub if ...

Page 6: Dziedziczenie   (cd.)

22 listopada 2000 Regula konkatenacji II 6

unit A: class(pfA); <declarationsA>begin <prologue_A>; inner; <epilogue_B>end A

unit B: A class(pfB); <declarationsB>begin <instructionsB>;end B

Klasę B należypojmować tak jak wtabelce obok.Słowo inner wskazujemiejsce włożeniainstrukcji klasydziedziczącej.

unit B: class(pfA,pfB); < declarationsA>; < declarationsB>begin < prologue_A >; < instructionsB >; < epilogue_B >end B

Page 7: Dziedziczenie   (cd.)

22 listopada 2000 Regula konkatenacji II 7

Przykład

Zaprogramujmy algorytm sortowania stogowego - heapsort unit heapsort: procedure(A: arrayof integer);

Przypomnijmy, że stóg możemy reprezentować jako tablicę.

Korzeniem stogu jest element A[1]. Synami elementu A[i] są A[2*i] (lewy syn) i A[2*i+1] (prawy syn), o ile istnieją tzn. mieszczą się w tablicy A. Takie drzewo jest binarne i doskonałe.

Dana tablica A nie musi być jednak stogiem, tzn. nie wiemy czy spełnia warunek A[i] < A[2*i] i A[i] < A[2*i+1].

Algorytm heapsort sprowadza się do dwu poleceń:

kopcuj - tzn. zbuduj kopiec z elementów tablicy A, stosując relację > zamiast <. Tak by korzeń był maksimum

sortuj - wstawiając korzeń na koniec i kopcując od nowa.

Page 8: Dziedziczenie   (cd.)

22 listopada 2000 Regula konkatenacji II 8

Struktura procedury

unit heapsort: procedure(A: arrayof integer); var unit kopcuj: procedure; … unit sortuj: procedure; ... Begin p := upperA); l := upper(A)div2 +1; call kopcuj; call sortuj; end heapsort;

Page 9: Dziedziczenie   (cd.)

22 listopada 2000 Regula konkatenacji II 9

Idea algorytmu kopcuj:

zauważmy, że w drugiej połowie tablicy A są liście, i że tworzą one las stogów,nasz algorytm będzie dołaczać do tego lasu kolejno elementy A[n/2 -1], A[n/2 -2], … , A[1], w taki sposób by zachować wlasność: elementy A[i],A[i+1], …, A[n] tworzą las stogów.

Dopóki nie dołaczono elementu A[1] powtarzaj

do ciągu A[i],A[i+1], … , A[n] stanowiącego las stogów dołącz element A[i-1] i w razie potrzeby spraw by ciąg elementów A[i-1],A[i], … , A[n] był znowu lasem stogów.

Zaprogramujmy ten krok wewnątrz pętli dopóki.

Page 10: Dziedziczenie   (cd.)

22 listopada 2000 Regula konkatenacji II 10

Załóżmy, że elementy A[l+1], … , A[n] stanowią las stogów.Niech i=l. Dołączamy element A[i]. Jeśli 2*i+1 < n, to istnieją obaj synowie tego elementu (A[2*i] i A[2*i+1]). Jeżeli przy tym obaj są mniejsi od A[i] to nic nie trzeba robić bo są (z założenia) korzeniami dwu stogów. Jeśli jeden z nich jest większy od A[i] to trzeba dokonać poprawy, w tym celu: a) wybieramy większego z dwu synów i zamieniamy jego wartośc z A[i],b) powtarzamy badanie dla odpowiedniego elementu A[2*i] (lub A[2*i+1]) aż do osiągnięcia pewności, że również oba poddrzewa węzła o numerze i-1 są stogami.

Page 11: Dziedziczenie   (cd.)

22 listopada 2000 Regula konkatenacji II 11

A oto kod tego algorytmu:

i:=l; j:= 2*i; x := A[i]; while {istnieje syn} do {A[j] jest większym z synów} if x >= A[j]then exit {już dobrze} fi; A[i] := A[j]; i := j; j:= 2*i; od; A[i] := x; {odłożone w czasie. Ale zdążyliśmy!}

Page 12: Dziedziczenie   (cd.)

22 listopada 2000 Regula konkatenacji II 12

A oto kod tego algorytmu:

j:= 2*i; x := A[i]; while j<= n {istnieje syn} do if j<n andif A[j]< A[j+1] then j:=j+1 fi; {A[j] jest większym z synów} if x >= A[j]then exit {już dobrze} fi; A[i] := A[j]; i := j; j:= 2*i; od; A[i] := x; {odłożone w czasie. Ale zdążyliśmy!}

Nazwijmy go przesiewanie.

Page 13: Dziedziczenie   (cd.)

22 listopada 2000 Regula konkatenacji II 13

Napiszmy teraz procedurę kopcuj

unit kopcuj: procedure;begin l:=(upper(A)div2)+1; do l:=l=1; if l=lower(A) then exit fi; {tu wpisujemy przesiewanie } odend kopcuj;

Page 14: Dziedziczenie   (cd.)

22 listopada 2000 Regula konkatenacji II 14

A teraz napiszmy procedurę sortuj

unit sortuj: procedure;begin p := upper(A); do x :=A(lower(A)); A(lower(A):=A[p]; A[p]:=x; p:=p-1;

if p=lowe(A)then exit fi; {tu wpisujemy przesiewanie } odend sortuj;

Page 15: Dziedziczenie   (cd.)

22 listopada 2000 Regula konkatenacji II 15

Łatwo zauważyć, że obie procedury mają część wspólną.Można to wykorzystać i napisać procedurę przesiewanie, która będzie wywoływana z obu procedur: kopcuj i sortuj.My jednak wykorzystamy dziedziczenie i stworzymy klasę przesiewanie, a procedury kopcuj i sortuj będą ją dziedziczyć.

Page 16: Dziedziczenie   (cd.)

22 listopada 2000 Regula konkatenacji II 16

unit przesiewanie: class; var koniec: Boolean;begin do inner; if koniec then exit fi; i:=l; j:=2*i; x := A[i]; while do if j<p andif A[j]<A[j+1] then j:=j+1 fi; if then exit fi; A[i]:=A[j]; i :=j; j := 2*i; od; A[i] := x; odend przesiewanie;

Page 17: Dziedziczenie   (cd.)

22 listopada 2000 Regula konkatenacji II 17

Nowa wersja procedury heapsort wygląda tak:Unit heapsort:procedure(A:arrayof integer); var i, j, l, p, x: integer; unit przesiewanie: class; … unit kopcuj: przesiewanie procedure; begin koniec:= l=lower(A); l:=l-1; end kopcuj; unit sortuj: procedure; begin koniec:=p=lower(A); x:=lower(A); A[lower(A)]:=A[p]; A[p]:=x; p:=p=1; end sortuj;begin l:=upper(A) div 2 +1; p:=upper(A); call kopcuj; call sortuj;end heapsort;

Page 18: Dziedziczenie   (cd.)

22 listopada 2000 Regula konkatenacji II 18

Podsumowanie

• Poznaliśmy lepiej regułę konkatenacji,

• Nauczyliśmy się wykorzystywać dziedziczenie do “wyciagania części wspólnej algorytmu przed nawias”

• Zobaczymy później jak tworzyć algorytmy abstrakcyjne posługując się dziedziczeniem i inner.

Page 19: Dziedziczenie   (cd.)

22 listopada 2000 Regula konkatenacji II 19

Zadanie:Napisać dwie wersje procedury heapsort i dokonać pomiarów czasu wykonania w celu porównania funkcji kosztu tych dwu algorytmów.

Pytania:

• czy można osiągnąć taki efekt w C++?

• czy można osiągnąć taki efekt w Javie?