Pobierz prezentację
Pobieranie prezentacji. Proszę czekać
OpublikowałIwona Wojtan Został zmieniony 10 lat temu
2
22 listopada 2000Regula konkatenacji II1 Dziedziczenie (cd.) Reguła konkatenacji II przykład - heapsort Reguła konkatenacji III
3
22 listopada 2000Regula konkatenacji II2 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
4
22 listopada 2000Regula konkatenacji II3 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?
5
22 listopada 2000Regula konkatenacji II4 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.
6
22 listopada 2000Regula konkatenacji II5 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...
7
22 listopada 2000Regula konkatenacji II6
8
22 listopada 2000Regula konkatenacji II7 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.
9
22 listopada 2000Regula konkatenacji II8 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;
10
22 listopada 2000Regula konkatenacji II9 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.
11
22 listopada 2000Regula konkatenacji II10 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.
12
22 listopada 2000Regula konkatenacji II11 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!}
13
22 listopada 2000Regula konkatenacji II12 A oto kod tego algorytmu: j:= 2*i; x := A[i]; while j = 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.
14
22 listopada 2000Regula konkatenacji II13 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 } od end kopcuj;
15
22 listopada 2000Regula konkatenacji II14 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 } od end sortuj;
16
22 listopada 2000Regula konkatenacji II15 Ł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ć.
17
22 listopada 2000Regula konkatenacji II16 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; od end przesiewanie;
18
22 listopada 2000Regula konkatenacji II17 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;
19
22 listopada 2000Regula konkatenacji II18 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.
20
22 listopada 2000Regula konkatenacji II19 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?
Podobne prezentacje
© 2024 SlidePlayer.pl Inc.
All rights reserved.