1 / 19

Dziedziczenie (cd.)

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

altessa
Download Presentation

Dziedziczenie (cd.)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Dziedziczenie (cd.) Reguła konkatenacji II przykład - heapsort Reguła konkatenacji III 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 Regula konkatenacji II

  3. unit bill: class(who: person, day: date); var amount: integer, is_paid: Boolean;  beginwriteln(«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? Regula konkatenacji II

  4. To słowo kluczowe może wystąpić w klasie dziedziczonej wszędzie tam, gdzie możemy napisać instrukcję. • Osiągniemy to stosując pseudoinstrukcję inner. • 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. 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 ... Regula konkatenacji II

  6. 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. Regula konkatenacji II

  8. Struktura procedury unit heapsort: procedure(A: arrayof integer);varunit kopcuj: procedure; …unit sortuj: procedure; ...Beginp := upperA); l := upper(A)div2 +1;call kopcuj;call sortuj; end heapsort; 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. 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. 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!} 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. 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; Regula konkatenacji II

  14. A teraz napiszmy procedurę sortuj unit sortuj: procedure;beginp := 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; 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ć. Regula konkatenacji II

  16. unit przesiewanie: class; var koniec: Boolean;begindo 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; 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; beginkoniec:= l=lower(A); l:=l-1; end kopcuj;unit sortuj: procedure;beginkoniec:=p=lower(A); x:=lower(A); A[lower(A)]:=A[p]; A[p]:=x; p:=p=1; end sortuj;beginl:=upper(A) div 2 +1; p:=upper(A);call kopcuj;call sortuj;end heapsort; 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. 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? Regula konkatenacji II

More Related