Wstęp do programowania / Ćwiczenia 8: Różnice pomiędzy wersjami

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Daria (dyskusja | edycje)
Naprzód!
 
Daria (dyskusja | edycje)
Chyba wystarcza 4 zadania
Linia 21: Linia 21:
       D = 100;
       D = 100;
  '''type''' Tab = array[0..D-1] of ^array[0..M-1];
  '''type''' Tab = array[0..D-1] of ^array[0..M-1];
      Str = record of
      Str = record  
        T:Tab;
        T:Tab;
        poczD,konD, poczM, konM:integer;
        poczD,konD, poczM, konM:integer;
      end;  
      end;  
Teraz dwie funkcje:
Teraz dwie funkcje:
  '''function''' Wstaw(var S:Str; liczba: integer):boolean;
  '''function''' Wstaw(var S:Str; liczba: integer):boolean;
Linia 31: Linia 31:
  //Wstaw staje się false wtedy i tylko wtedy gdy struktura S jest pełna  
  //Wstaw staje się false wtedy i tylko wtedy gdy struktura S jest pełna  
  '''begin'''
  '''begin'''
'''if''' (S.konD=S.poczD '''and''' S.konM+1=S.poczM) '''or''' ((S.konD+1) mod D = S.poczD '''and''' S.konM=M-1 '''and''' S.poczM=0) '''then'''
  '''if''' (S.konD=S.poczD '''and''' S.konM+1=S.poczM) '''or''' ((S.konD+1) mod D = S.poczD '''and''' S.konM=M-1 '''and''' S.poczM=0) '''then'''
  Wstaw:=false
    Wstaw:=false
'''else''' '''begin'''
  '''else''' '''begin'''
  Wstaw:=true;
    Wstaw:=true;
  '''if''' S.konM = 0 '''and''' S.poczD <>S.konD '''then''' New(S.T[S.konD]);
    '''if''' S.konM = 0 '''and''' S.poczD <>S.konD '''then''' New(S.T[S.konD]);
  S.T[S.konD]^[S.konM]:=liczba;
    S.T[S.konD]^[S.konM]:=liczba;
  S.komM:=(S.komM+1) mod M;
    S.komM:=(S.komM+1) mod M;
  '''if''' S.konM=0 '''then''' S.konD:=(S.konD+1) mod D;
    '''if''' S.konM=0 '''then''' S.konD:=(S.konD+1) mod D;
'''end''';
  '''end''';
  '''end''';
  '''end''';
''Koszt czasowy'': stały
''Koszt czasowy'': stały
Linia 49: Linia 49:
  //Pobierz staje się false wtedy i tylko wtedy gdy struktura S jest pusta  
  //Pobierz staje się false wtedy i tylko wtedy gdy struktura S jest pusta  
  '''begin'''
  '''begin'''
'''if''' (S.konD=S.poczD '''and''' S.konM=S.poczM) '''then'''
  '''if''' (S.konD=S.poczD '''and''' S.konM=S.poczM) '''then'''
  Pobierz:=false
    Pobierz:=false
'''else''' '''begin'''
  '''else''' '''begin'''
  Pobierz:=true;
    Pobierz:=true;
  liczba:=S.T[S.poczD]^[S.poczM];   
    liczba:=S.T[S.poczD]^[S.poczM];   
  S.poczM:=(S.poczM+1) mod M;
    S.poczM:=(S.poczM+1) mod M;
  '''if''' S.poczM=0 '''then''' '''begin'''
    '''if''' S.poczM=0 '''then''' '''begin'''
    '''if''' S.konD <> S.pocz '''then''' Dispose(S.T[poczD]);
      '''if''' S.konD <> S.pocz '''then''' Dispose(S.T[poczD]);
    S.poczD:=(S.poczD+1) mod D;
      S.poczD:=(S.poczD+1) mod D;
    '''end''';
   '''end''';
   '''end''';
'''end''';
  '''end''';
  '''end''';
''Koszt czasowy'': stały
''Koszt czasowy'': stały
Linia 68: Linia 68:
== Zadanie 2 (Haszowanie)==
== Zadanie 2 (Haszowanie)==
Zaimplementuj strukturę danych z operacjami:
Zaimplementuj strukturę danych z operacjami:
# Wstaw(Klucz: integer; var d: Dane); (var zwiększa efektywność)  
# Wstaw(klucz: integer; var d: Dane); (var zwiększa efektywność)  
# Daj(var Klucz: Integer; var d: Dane);
# Daj(var klucz: integer; var d: Dane);
Wstaw wstawia do struktury danych parę (klucz, napis) lub (klucz,
Wstaw wstawia do struktury danych parę (klucz, napis) lub (klucz,
liczba), gdzie napis jest typu string, zaś liczba typu integer.
liczba), gdzie napis jest typu string, zaś liczba typu integer.
Podaj stosowną deklarację dla typu Dane. Do przechowywania informacji
Podaj stosowną deklarację dla typu Dane. Do przechowywania informacji
użyj tablicy [0..N] elementów odpowiedniego typu. Wstawianie ma polegać na obliczeniu klucz mod (N+1), jeśli pod tym indeksem jest wolne miejsce w tablicy to wstawiamy, w przeciwnym przypadku szukamy liniowo (cyklicznie) pierwszego wolnego miejsca. Wyszukiwanie analogicznie. Zakładamy, że nigdy nie będzie wkładane więcej niż N elementów (to m.in. upraszcza wyszukiwanie, zawsze jest co najmniej jedno wolne miejsce).
użyj tablicy [0..N] elementów odpowiedniego typu. Wstawianie ma polegać na obliczeniu klucz mod (N+1), jeśli pod tym indeksem jest wolne miejsce (-1) to wstawiamy, w przeciwnym przypadku szukamy liniowo (cyklicznie) pierwszego wolnego miejsca. Wyszukiwanie analogicznie. Zakładamy, że nigdy nie będzie wkładane więcej niż N elementów (to m.in. upraszcza wyszukiwanie indeksu dla danego klucza, zawsze jest co najmniej jedno wolne miejsce).
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Wskazówka 1'''
<div class="mw-collapsible-content" style="display:none">
Typ Dane to rekord z wariantami string i integer. Dane nie nadaje się na typ elementów tablicy; tam lepiej użyć rekord z wariantami
wskaźnik do napisu i liczba. Można by tak zdefiniować też Dane, ale nie widać ku temu powodów.
</div>
</div>
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Rozwiązanie 1''' 
<div class="mw-collapsible-content" style="display:none">
'''const''' N = 100;
'''type''' rodzaj = (napis, liczba)
      Dane = record
        case co:rodzaj of
          napis: (s:string)
          liczba: (l:liczba)
        end;
      Eltab = record
        klucz:integer;
        case co:rodzaj of
          napis: (wsk:^string)
          liczba: (l:liczba)
        end;
'''var''' T: array[0..N] of Eltab
Teraz dwie procedury:
'''procedure''' Wstaw(klucz: integer; var d: Dane);
//wstawiamy dane z d do tablicy T na pierwsze wolne miejsce zaczynając od indeksu klucz mod (N+1)
//zakładamy, że są wolne miejsca w tablicy T
'''var''' k:integer;
'''begin'''
  k:=klucz mod (N+1);
  '''while''' T[k].klucz <> -1 '''do''' k:=(k+1) mod (N+1);
  T[k].klucz:=klucz;
  T[k].co:=d.co;
  '''case''' d.co '''of'''
    napis: New(T[k].wsk); T[k].wsk^:=d.s;
    liczba: T[k].l:=d.l
  '''end''';
'''end''';
''Koszt czasowy'': liniowy względem N
 
''Koszt pamięciowy'': stały
'''function''' Daj(klucz: integer; var d: Dane):boolean;
//pobieramy liczbę lub napis z tablicy T skojarzonych z kluczem klucz
//zakładamy, że są wolne miejsca w tablicy T
'''var''' i:integer;
'''begin'''
  k:=klucz mod (N+1);
  '''while''' T[k].klucz <> klucz '''and''' T[k].klucz <> -1 '''do''' k:=(k+1) mod (N+1);
  '''if''' T[k].klucz = -1 '''then'''
    Daj:=false
  '''else''' '''begin'''
    Daj:=true;
    d.co:=T[k].co;
    '''case''' d.co '''of'''
      napis: d.s:=T[k].wsk^;
      liczba: d.l:=T[k].l;
    '''end''';
  '''end''';
'''end''';
''Koszt czasowy'': liniowy względem N
 
''Koszt pamięciowy'': stały
</div>
</div>
 
== Zadanie 3 (New i dispose dla typu T)==
 
Zaimplementuj własne operacje new i delete dla elementów typu T. Użyj w tym celu tablicy [1..N] zawierającej rekordy z dwoma wariantami:
# pole typu T
# pole(-a) z pewnymi dodatkowymi informacjami (jakimi?)
 
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Wskazówka 1'''  
'''Wskazówka 1'''  
<div class="mw-collapsible-content" style="display:none">
<div class="mw-collapsible-content" style="display:none">
Typ Dane to rekord z wariantami (string i integer). Oczywiście Dane
W elementach tablicy albo trzymamy dane, albo indeks następnego wolnego elementu tablicy (trzeba jeszcze gdzieś pamiętać indeks pierwszego wolnego elementu).
nie nadaje się na typ eltów tablicy, tam trzeba rekordu z wariantami
(wskażnik do napisu i liczba). Można by tak zdefiniować też Dane, ale nie widać ku temu powodów.
</div>
</div>
</div>
</div>
Linia 86: Linia 157:
'''Rozwiązanie 1'''   
'''Rozwiązanie 1'''   
<div class="mw-collapsible-content" style="display:none">
<div class="mw-collapsible-content" style="display:none">
'''const''' N = 100;
'''type''' rodzaj = (pełny, pusty);
      Eltab = record
        case rodzaj of
          pełny: (d:T)
          pusty: (nast:integer)
        end;
      Str = record
        T:array[1..N] of Eltab;
        pierwszy:integer;
      end;
Inicjalizacja T, funkcja NewT i procedura DisposeT:
'''procedure''' InitT(var S:Str);
//wszystkie pola ustawiamy na puste, nast wskazują na następne pole lub zero; pierwszy staje sie równy 1
'''var''' i:integer;
'''begin'''
  '''for''' i:=1 '''to''' N '''do''' S.T[i].nast:=(i+1) mod (N+1);
  S.pierwszy:=1;
'''end''';
''Koszt czasowy'': liniowy względem N


''Koszt pamięciowy'': stały
'''function''' NewT(var S:Str; var nowy:integer):boolean;
//nowy to indeks któregoś z dotychczas pustych pól w S.T; jeśli takich nie ma to New będzie miało wartość false
'''begin'''
  '''if''' S.pierwszy = 0 '''then'''
    New:=false
  '''else''' '''begin'''
    New:=true;
    nowy:=S.pierwszy;
    S.pierwszy:=S.T[S.pierwszy].nast;
  '''end''';
'''end''';
''Koszt czasowy'': stały
''Koszt pamięciowy'': stały
'''procedure''' DisposeT(var S:Str; d:integer);
//zwalniamy indeks d w tablicy S.T
'''begin'''
  S.T[d].nast:=S.pierwszy;
  S.pierwszy:=d;
'''end''';
''Koszt czasowy'': stały
''Koszt pamięciowy'': stały
</div>
</div>
== Zadanie 4 (Sortowanie tablicy wskaźników do napisów)==
Dana jest tablica A typu array[1..N] of ^string. Posortuj tę tablice używając porządku leksykograficznego (słownikowego) na słowach. Załóż, że dana jest funkcja compare(s,t:string):boolean, która ma wartość true wtedy i tylko wtedy gdy słowo s jest leksykograficznie mniejsze od słowa t.
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Wskazówka 1'''
<div class="mw-collapsible-content" style="display:none">
Użyj dowolnego algorytmu sortowania. Zamiast przesuwać obiekty przesuwaj wskaźniki.
</div>
</div>
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Rozwiązanie 1''' 
<div class="mw-collapsible-content" style="display:none">
'''procedure''' Sort(var A:array[1..N] of ^string);
//sortujemy leksykograficznie tablicę wskażników do słów
'''var''' i,j,min: integer;
    pom: ^string;
'''begin'''
  '''for''' i:=1 '''to''' N '''do''' '''begin'''
    min:=i;
    '''for''' j:=i+1 '''to''' N '''do'''
      '''if''' compare(A[j]^,A[i]^) '''then''' min:=j;
    pom:=A[i];
    A[i]:=A[min];
    A[min]:=pom;
  '''end''';
'''end''';
''Koszt czasowy'': kwadratowy względem N
''Koszt pamięciowy'': stały
</div>
</div>
</div>
</div>

Wersja z 17:41, 26 lip 2006

To są zadania na wskaźniki

Zadanie 1 (Tablica wskaźników do tablic)

Zaimplementuj strukturę danych reprezentującą ciąg liczb z operacjami:

  1. wstaw liczbę na koniec ciągu,
  2. pobierz (usuwając) pierwszą liczbę ciągu.

Użyj w tym celu tablicy wskaźników do tablic, gdzie tablice składowe są przydzielane i zwalniane w miarę potrzeby (zaletą tej implementacji jest to, że dość elastycznie dostosowuje się do aktualnego rozmiaru ciągu, nie wymagając tylu wskaźników co zwykła lista).

Wskazówka 1

Rozwiązanie 1

Zadanie 2 (Haszowanie)

Zaimplementuj strukturę danych z operacjami:

  1. Wstaw(klucz: integer; var d: Dane); (var zwiększa efektywność)
  2. Daj(var klucz: integer; var d: Dane);

Wstaw wstawia do struktury danych parę (klucz, napis) lub (klucz, liczba), gdzie napis jest typu string, zaś liczba typu integer. Podaj stosowną deklarację dla typu Dane. Do przechowywania informacji użyj tablicy [0..N] elementów odpowiedniego typu. Wstawianie ma polegać na obliczeniu klucz mod (N+1), jeśli pod tym indeksem jest wolne miejsce (-1) to wstawiamy, w przeciwnym przypadku szukamy liniowo (cyklicznie) pierwszego wolnego miejsca. Wyszukiwanie analogicznie. Zakładamy, że nigdy nie będzie wkładane więcej niż N elementów (to m.in. upraszcza wyszukiwanie indeksu dla danego klucza, zawsze jest co najmniej jedno wolne miejsce).

Wskazówka 1

Rozwiązanie 1

Zadanie 3 (New i dispose dla typu T)

Zaimplementuj własne operacje new i delete dla elementów typu T. Użyj w tym celu tablicy [1..N] zawierającej rekordy z dwoma wariantami:

  1. pole typu T
  2. pole(-a) z pewnymi dodatkowymi informacjami (jakimi?)

Wskazówka 1

Rozwiązanie 1

Zadanie 4 (Sortowanie tablicy wskaźników do napisów)

Dana jest tablica A typu array[1..N] of ^string. Posortuj tę tablice używając porządku leksykograficznego (słownikowego) na słowach. Załóż, że dana jest funkcja compare(s,t:string):boolean, która ma wartość true wtedy i tylko wtedy gdy słowo s jest leksykograficznie mniejsze od słowa t.

Wskazówka 1

Rozwiązanie 1