Zadanie. Przypuśćmy, że dana jest tablica jednowymiarowa zawierająca N ∈ ℕ elementów.
Algorytm rekurencyjny wypisujący elementy tej tablicy, zaczynając od pierwszego
można zapisać następująco:
Jeżeli tablica jest niepusta, to
Wypisz pierwszy element,
Wypisz tablicę zawierającą pozostałe N − 1 elementy.
Napisz procedurę Wypisz_Tablice realizującą ten algorytm w przypadku, gdy elementy
tablicy są typu Integer, przy czym parametr formalny rodzaju wejściowego ma
być typu:
type Integer_Array is array (Integer range <>) of Integer;
i przy realizacji algorytmu wolno korzystać jedynie z atrybutów typów tablicowych.
Rozwiązanie
PROCEDURE Wypisz_Tablice (
T : IN OUT Integer_Array) IS
BEGIN
IF T'Length=1 THEN
Put(T(1));
ELSE
Put(T(1));
New_Line;
DECLARE
T2 : Integer_Array (1 .. T'Length - 1);
BEGIN
FOR I IN 1..T2'Length LOOP
T2(I):=T(I+1);
END LOOP;
Wypisz_Tablice(T2);
END;
END IF;
END Wypisz_Tablice;
Zadanie. Przypuśćmy, że dana jest tablica jednowymiarowa zawierająca N ∈ ℕ elementów.
Algorytm rekurencyjny wypisujący elementy tej tablicy zaczynając od ostatniego
można zapisać następująco:
Jeżeli tablica jest niepusta, to
Wypisz ostatni element,
Wypisz tablicę zawierającą pozostałe N − 1 elementy.
Napisz procedurę Wypisz_Tablice_Od_Konca realizującą ten algorytm w przypadku,
gdy elementy tablicy są typu Integer, przy czym parametr formalny rodzaju wejściowego
ma być typu:
type Integer_Array is array (Integer range <>) of Integer;
i przy realizacji algorytmu wolno korzystać jedynie z atrybutów typów tablicowych.
Rozwiązanie
PROCEDURE Wypisz_Tablice_od_Konca (
T : IN OUT Integer_Array) IS
BEGIN
IF T'Length=1 THEN
Put(T(T'Last));
ELSE
Put(T(T'Last));
New_Line;
DECLARE
T2 : Integer_Array (1 .. T'Length - 1);
BEGIN
FOR I IN 1..T2'Length LOOP
T2(I):=T(I);
END LOOP;
Wypisz_Tablice_od_Konca(T2);
END;
END IF;
END Wypisz_Tablice_od_Konca;
Zadanie. Przypuśćmy, że mamy wyznaczyć iloczyn liczb M ∈ ℤ i N ∈ P i nie możemy
skorzystać z tabliczki mnożenia, natomiast możemy wyłącznie stosować dodawanie. Algorytm
rekurencyjny wyznaczający M ∗ N jest następujący:
Jeżeli N = 1, to M ∗ N = M ,
w przeciwnym przypadku M ∗ N = M + M ∗ (N − 1).
Napisać funkcję Mnozenie, która realizuje ten algorytm.
Rozwiązanie
FUNCTION Mnozenie (
M : Integer;
N : Positive)
RETURN Integer IS
M1: Integer :=M ;
N1: Positive :=N;
BEGIN
WHILE N1/=1 LOOP
M1:=M1+M;
N1:=N1-1;
END LOOP;
RETURN M1;
END Mnozenie;
Zadanie. Mamy dane deklaracje:
type Wsk_Integer is access Integer;
Wsk1, Wsk2 : Wsk_Integer;
oraz instrukcje
Wsk1 := new Integer'(0);
Wsk2 := new Integer'(100);
Put (Wsk1.All, 3); New_Line;
Put (Wsk2.All, 3); New_Line;
Wsk2.All := Wsk1.All;
Put (Wsk1.All, 3); New_Line;
Put (Wsk2.All, 3); New_Line;
Wsk1.All := 5;
Wsk2.All := 25;
Put (Wsk1.All, 3); New_Line;
Put (Wsk2.All, 3); New_Line;
Wsk1 := Wsk2;
Put (Wsk1.All, 3); New_Line;
Put (Wsk2.All, 3); New_Line;
Podaj wszystkie wartości wypisywane przez wywołania procedury Put.
Rozwiązanie
0 100 0 0 5 25 25 25
Zadanie. Przypuśćmy, że chcemy wyznaczać wartości dowolnych, dobrze określonych
odwzorowań F: ℝ → ℝ
W tym celu piszemy deklaracje
type Wektor_2 is array (1 .. 2) of Float;
type Odwzorowanie is access function (X : in Wektor_2) return Wektor_2;
Napisać funkcję Obraz, której parametrami są argument X typu Wektor_2 i funkcja
typu Odwzorowanie. Funkcja ma wyznaczać wektor Odwzorowanie(X). Następnie
napisać funkcje Przeciwny i Obrocony_O_90 obliczające odpowiednio wektor przeciwny
do argumentu tej pierwszej funkcji i wektor obrócony o kąt o 90 do argumentu drugiej
funkcji, takie, że mogą być parametrami aktualnymi funkcji Obraz. Mając deklaracje
V : Wektor_2 := (1.0, 1.0);
W : Wektor_2;
napisać instrukcje przypisujące zmiennej W wartości obliczone przez funkcję Obraz w
przypadku, gdy jej parametrami aktualnymi są V i funkcje Przeciwny i
Obrocony_O_90.
Rozwiązanie
TYPE Wektor_2 IS ARRAY (1 .. 2) OF Float;
TYPE Odwzorowanie IS ACCESS FUNCTION
(X : IN Wektor_2) RETURN Wektor_2;
FUNCTION Przeciwny (
X : IN Wektor_2)
RETURN Wektor_2 IS
Y : Wektor_2;
BEGIN
Y(1):=-X(1);
Y(2):=-X(2);
RETURN Y;
END Przeciwny;
FUNCTION Obrocony_O_90 (
X : IN Wektor_2)
RETURN Wektor_2 IS
Y : Wektor_2;
BEGIN
Y(1):=-X(2);
Y(2):=X(1);
RETURN Y;
END Obrocony_O_90;
FUNCTION Obraz (
X : IN Wektor_2;
Funkcja : IN Odwzorowanie)
RETURN Wektor_2 IS
Y : Wektor_2;
BEGIN
Y:=Funkcja(X);
RETURN Y;
END Obraz;
Funkcja : Odwzorowanie;
V : Wektor_2 := (1.0, 1.0);
Y : Wektor_2;
BEGIN
Funkcja:=Przeciwny'ACCESS;
Y:=Obraz(V,Funkcja);
Put(Y(1));
New_Line;
PUT(Y(2));
New_line;
Funkcja:=Obrocony_O_90'ACCESS;
Y:=Obraz(V,Funkcja);
Put(Y(1));
New_Line;
PUT(Y(2);
Zadanie. Napisać funkcje First_Component i Second_Component obliczające odpowiednio
pierwszą i drugą składową wektora typu Wektor_2D. Założyć przy tym, że
deklaracja tego typu ma postać
type Wektor_2D is private;
:
private
type Wektor_2D is record
First : Float;
Second : Float;
end record;
Rozwiązanie
FUNCTION First_Component (
X : Wektor_2d)
RETURN Float IS
BEGIN
RETURN X.First;
END First_Component;
FUNCTION SECOND_Component (
X : Wektor_2d)
RETURN Float IS
BEGIN
RETURN X.Second;
END SECOND_Component;
Zadanie. Przyjmując definicję typu Wektor_2D jak wyżej napisać funkcje
Konstruktor_2D, "+", "*", "*" służące odpowiednio do: konstrukcji wektora z jego
składowych, obliczania sumy dwóch wektorów i obliczania iloczynu skalara przez wektor i
wektora przez skalar rzeczywisty.
Rozwiązanie
FUNCTION "+" (
X,
Y : Wektor_2d)
RETURN Wektor_2d IS
V : Wektor_2d;
BEGIN
V.First:=X.First+Y.First;
V.Second:=X.Second+Y.Second;
RETURN V;
END "+";
FUNCTION "*" (
A : Float;
X : Wektor_2d)
RETURN Wektor_2d IS
V : Wektor_2d;
BEGIN
V.First:=A*X.First;
V.Second:=A*X.Second;
RETURN V;
END "*";
FUNCTION "*" (
X : Wektor_2d;
A : Float)
RETURN Wektor_2d IS
BEGIN
RETURN A*X;
END "*";
PROCEDURE Czytaj_Wektor_2d (
X : OUT Wektor_2d) IS
BEGIN
Ada.Float_Text_Io.Get (X.First);
New_Line;
Ada.Float_Text_Io.Get (X.Second);
END Czytaj_Wektor_2d;
Zadanie. Przyjmując definicję typu Wektor_2D jak wyżej napisać pełne deklaracje
stałych Zero, Wersor_1 i Wersor_2, które reprezentują odpowiednio wektory:
0 = (0,0) , 1 e = (1,0) , 2 e = (0,1)
Rozwiązanie
PRIVATE
TYPE Wektor_2D IS
RECORD
First : Float;
Second : Float;
END RECORD;
Zero: CONSTANT Wektor_2D := (0.0,0.0);
E1: CONSTANT Wektor_2D := (1.0,0.0);
E2: CONSTANT Wektor_2D := (0.0,1.0);
Zadanie. Mamy deklaracje
generic
type Typ_Danych is private;
procedure Wymien_Ogolnie (W1, W2 : in out Typ_Danych);
...
procedure Wymien_Ogolnie (W1, W2 : in out Typ_Danych) is
Temp: Typ_Danych;
begin
Temp := W1;
W1 := W2;
W2 := Temp;
end Wymien_Ogolnie;Czy typ Typ_Danych zadeklarowany w sekcji ogólnej jako
private, może być typem prywatnym ograniczonym - limited private? Uzasadnij
odpowiedź.
Rozwiązanie
Nie może być gdyż typ limited private nie ma zdefiniowanego działania „:=”
Zadanie. Mamy deklaracje
generic
type Typ_Danych is private;
procedure Wymien_Ogolnie (W1, W2 : in out Typ_Danych);
Napisać konkretyzację procedury Wymien_Ogolnie w przypadku typu standardowego
Character.
Rozwiązanie
Zad 16.2
PROCEDURE Wymien_Integer IS
NEW Wymien_Ogolnie (Typ_Danych => Character);
Zadanie. Mamy deklaracje
generic
type Typ_Danych is private;
with function Wiekszy(L, R : Typ_Danych) return Boolean;
function Maksimum (W1, W2 : Typ_Danych) return Typ_Danych;Napisać
konkretyzację funkcji Maksimum w przypadku typu standardowego Character.
Rozwiązanie
FUNCTION Maksimum_Character IS
NEW Maksimum (
Typ_Danych => Character,
Wiekszy => ">");