• Nie Znaleziono Wyników

Algorytmy 2 Laboratorium: tablica dynamiczna

N/A
N/A
Protected

Academic year: 2021

Share "Algorytmy 2 Laboratorium: tablica dynamiczna"

Copied!
4
0
0

Pełen tekst

(1)

Algorytmy 2

Laboratorium: tablica dynamiczna

Przemysław Klęsk 14 października 2020

1 Cel

Celem zadania jest wykonanie implementacji struktury danych nazywanej tablicą dynamiczną (ang. dy- namic array). Jest to jedna z najbardziej podstawowych liniowych struktur danych i jednocześnie baza do tworzenia bardziej zaawansowanych struktur takich jak np. kopiec czy tablica mieszająca. Nazwa

— tablica dynamiczna — wynika z faktu, że struktura ta w sposób dynamiczny powiększa swój roz- miar, gdy zachodzi taka potrzeba. Przyjmuje się pewien stały współczynnik powiększania (np. 1.5, 2.0) i po wyczerpaniu aktualnego rozmiaru tablicy próba dodania kolejnego elementu wymaga następujących czynności:

- zaalokowania większego (ciągłego) fragmentu pamięci na nową tablicę (stanowiącego np. odpowied- nio 150% lub 200% poprzedniego rozmiaru),

- przepisania dotychczasowej zawartości ze starego miejsca w nowe, - dopisania nowego elementu,

- uwolnienia pamięci zajmowanej przez starą tablicę.

Tym samym operacja dodawania pojedynczego elementu w przypadku optymistycznym (i typowym) ma stałą złożoność obliczeniową — Θ(1), zaś w przypadku pesymistycznym (opisanym powyżej) ma złożoność liniową — Θ(n). Należy jednocześnie zauważyć, że w związku z geometrycznym wzrostem rozmiaru ta- blicy, kolejne momenty wymagające przepisania zawartości, czyli kosztu liniowego, będą zachodziły coraz rzadziej, z częstością gasnącą również geometrycznie (wykładniczo). Tym samym można pokazać mate- matycznie, że tzw. zamortyzowana złożoność obliczeniowa operacji dodawania pozostaje stała — Θ(1)

— co jest ważnym faktem motywującym powszechne stosowanie tej struktury danych. Należy przy tym zwrócić uwagę na podstawową zaletę używania tablicy czyli stały czasu dostępu do dowolnego elementu

— Θ(1) — w odróżnieniu np. od list, gdzie czas dostępu jest liniowy.

Dodatkowym celem zadania jest wykonanie odpowiednich pomiarów czasowych obrazujących wspo- mniane powyżej fakty tyczące złożoności obliczeniowej. W ramach głównego eksperymentu, polegającego na dodawaniu dużej liczby elementów do tablicy dynamicznej, chcielibyśmy obserwować: czasy kolejnych pesymistycznych operacji dodawania, czas całkowity i czas zamortyzowany.

1

(2)

2 Instrukcje, wskazówki, podpowiedzi

1. Podobnie jak w poprzednim zadaniu dozwolone są zarówno implementacja strukturalna jak i obiek- towa, przy czym ponownie wymagane jest użycie mechanizmu szablonów (template) języka C++

dla zachowania ogólności.

2. Struktura (lub klasa) reprezentująca tablicę dynamiczną powinna zawierać: informacje o aktualnie faktycznym i maksymalnym rozmiarze oraz właściwą tablicę z danymi (lub wskaźnikami na dane)

— deklaracyjnie np.: T* array;, gdzie T jest dowolnym typem.

3. Można przyjąć początkowy maksymalny rozmiar tablicy równy 1 i współczynnik rozszerzania równy 2.0.

4. Interfejs tablicy dynamicznej powinien udostępniać następujące funkcje / metody:

(a) dodanie nowego elementu na końcu tablicy (argument: dane),

(b) zwrócenie danych i-tego elementu tablicy (argument: indeks i żądanego elementu (numerując od zera); wynik: dane i-tego elementu lub niepowodzenie w razie indeksu poza zakresem), (c) ustawienie (podmiana) danych i-tego elementu tablicy (argument: indeks i żądanego elementu

(numerując od zera) oraz nowe dane; wynik: pusty lub niepowodzenie w razie indeksu poza zakresem),

(d) czyszczenie tablicy tj. usunięcie wszystkich elementów,

(e) zwrócenie napisowej reprezentacji tablicy — np. funkcja / metoda to string(...) (format wyniku wg uznania programisty, może zawierać np. aktualny rozmiar tablicy, aktualny maksy- malny rozmiar tablicy, wypis pewnej liczby elementów początkowych / końcowych, opcjonalnie adres tablicy w pamięci; argumenty: również wg uznania programisty — np. liczba elementów do wypisania, wskaźnik na funkcję wypisującą pojedynczy rekord danych).

(f) bąbelkowe posortowanie tablicy (argument: wskaźnik na komparator lub brak argumentu przy założeniu istnienia przeciążonego operatora < lub >); uwaga: sortowanie ma odbywać się w miejscu.

5. W programie można wykorzystać ogólne wskazówki z poprzedniego zadania dotyczące:

- dynamicznego zarządania pamięcią (new, delete) — w szczególności przemyślenia miejsc od- powiedzialnych za uwalnianie pamięci danych,

- przeciążenia operatora indeksowania (operator []),

- wydzielenia implementacji interfejsu tablicy dynamicznej do odrębnego pliku .h, - pracy z napisami (użycie typu std::string),

- pomiaru czasu (funkcja clock() po dołączeniu #include <time.h>),

- użycia wskaźników na funkcje (np. w trakcie wykonania funkcji to string(...)), - generowania losowych danych (funkcje rand() i srand(...)).

2

(3)

3 Zawartość funkcji main()

Główny eksperyment zawarty w funkcji main() ma polegać na dodawaniu dużej liczby elementów (da- nych) do tablicy dynamicznej, np. rzędu 107. Towarzyszyć mają temu pomiary czasowe. Poniższy listing pokazuje schemat eksperymentu (proszę traktować go jako poglądowy przykład):

int main () {

...

dynamic_array < s o m e _ o b j e c t * >* da = new dynamic_array < s o m e _ o b j e c t * >() ; // s t w o r z e n i e t a b l i c y

const int order = 7; // rzad w i e l k o s c i r o z m i a r u d o d a w a n y c h d a n y c h const int n = pow (10 , order ) ; // r o z m i a r d a n y c h

// d o d a w a n i e do t a b l i c y c l o c k _ t t1 = clock () ;

double m a x _ t i m e _ p e r _ e l e m e n t = 0.0; // n a j g o r s z y z a o b s e r w o w a n y czas o p e r a c j i d o d a w a n i a for ( int i = 0; i < n ; i ++) {

s o m e _ o b j e c t * so = ... // l o s o w e dane c l o c k _ t t 1 _ e l e m e n t = clock () ; da - > add ( so ) ;

c l o c k _ t t 2 _ e l e m e n t = clock () ;

double t i m e _ p e r _ e l e m e n t = ... // o b l i c z e n i e c z a s u p o j e d y n c z e j o p e r a c j i d o d a w a n i a if ( t i m e _ p e r _ e l e m e n t > m a x _ t i m e _ p e r _ e l e m e n t )

{

... // o d n o t o w a n i e n o w e g o n a j g o r s z e g o c z a s u i k o m u n i k a t i n f o r m a c y j n y na e k r a n ( przy k t o r y m i n d e k s i e m i a l o to m i e j s c e )

} }

c l o c k _ t t2 = clock () ;

... // w y p i s na e k r a n a k t u a l n e j p o s t a c i t a b l i c y ( s k r o t o w e j ) i p o m i a r o w c z a s o w y c h ( czas c a l k o w i t y i z a m o r t y z o w a n y )

da - > clear ( true ) ; // c z y s z c z e n i e t a b l i c y wraz z u w a l n i a n i e m p a m i e c i d a n y c h delete da ;

return 0;

}

4 Sprawdzenie antyplagiatowe — przygotowanie wiadomości e-mail do wysłania

1. Kod źródłowy programu po sprawdzeniu przez prowadzącego zajęcia laboratoryjne musi zostać przesłany na adres algo2@zut.edu.pl.

2. Plik z kodem źródłowym musi mieć nazwę wg schematu: nr albumu.algo2.nr lab.main.c (plik może mieć rozszerzenie .c lub .cpp). Przykład: 123456.algo2.lab06.main.c (szóste zadanie laboratoryjne studenta o numerze albumu 123456). Jeżeli kod źródłowy programu składa się z wielu plików, to należy stworzyć jeden plik, umieszczając w nim kody wszystkich plików składowych.

3. Plik musi zostać wysłany z poczty ZUT (zut.edu.pl).

3

(4)

4. Temat maila musi mieć postać: ALGO2 IS1 XXXY LAB06, gdzie XXXY to numer grupy (np. ALGO2 IS1 210C LAB06).

5. W pierwszych trzech liniach pliku z kodem źródłowym w komentarzach muszą znaleźć się:

- informacja identyczna z zamieszczoną w temacie maila (linia 1), - imię i nazwisko autora (linia 2),

- adres e-mail (linia 3).

6. Mail nie może zawierać żadnej treści (tylko załącznik).

7. W razie wykrycia plagiatu, wszytkie uwikłane osoby otrzymają za dane zadanie ocenę 0 punktów (co jest gorsze niż ocena 2 w skali {2, 3, 3.5, 4, 4.5, 5}).

4

Cytaty

Powiązane dokumenty

0 2 Patrz Śliwiński: Prawo karne, C zęść szczególna, s. Stanowisko SN nie wydaje się trafne. Jak już zostało wyżej podniesione, fakt porzucenia zabranej rzeczy nie

two przez zabór określa działanie polegające na wyjęciu mienia spod władztwa osoby władającej mieniem i przeniesienia tego mienia we władztwo sprawcy zaboru.53 Podobnie w

I spełnienie warunków równowagi dla całego układu i dowolnego podukładu (np. węzła

// utworzono tablicę 10 referencji typu String, naleŜy dla kaŜdego elementu tablicy przydzielić pamięć. • Przydział pamięci na elementy

[∗∗] Wiemy, że dolna granica na liczbę wykonywanych porównań przez dowolny algorytm znajdujący minimum w n–elementowym zbiorze wynosi n − 1.. Dolna granica na

[∗∗] Wiemy, że dolna granica na liczbę wykonywanych porównań przez dowolny algorytm znajdujący minimum w n–elementowym zbiorze wynosi n − 1.. Dolna granica na

Następnym, bardzo ważnym, elementem towarzyszącym procesowi wybuchu są gazowe produkty wybuchu (GPW), które mają za zadanie przenosić wysokie ciśnienie i są

(pierwszy | drugi), (trzeci | czwarty) Liczności wystąpień elementów – deklarujemy przy określaniu zawartości.  Domyślnie element musi wysąpić