Zbiorcza lista zadań z Pascala

Transkrypt

Zbiorcza lista zadań z Pascala
1
Zbiorcza lista zadań z Pascala
Pisząc pierwsze programy proszę zwrócić szczególną uwagę na pojęcie procedury (a
także funkcji). Celem początkowych zajęć jest wyrobienie umiejętności korzystania
z procedur, posługiwania się parametrami procedur, przekazywania informacji za
pomocą parametrów, tworzenia strukturalnych programów.
Zad. 1. (Zadanie 1 z listy 1 dr Heleny Krupickiej). Dany jest wielomian W (x) =
a0 · xn + a1 · xn−1 + . . . + an . Napisz program, który:
1) wczyta: stopień wielomianu W i jego całkowite współczynniki (od a0 do an ),
2) wypisze ten wielomian,
3) obliczy jego pochodną,
4) wypisze tę pochodną,
5) za pomocą schematu Hornera obliczy wartość pochodnej w punkcie 2 i wypisze ją.
Uwaga: wielomian należy wypisać czytelnie, bez składników o zerowych współczynnikach (za wyjątkiem wielomianu zerowego) i bez zbędnych operatorów +.
Przykład wyników dla danych n = 5 i współczynników 2 0 0 3 0 −1:
W (x) = 2 · x5 + 3 · x2 − 1 · x0 .
W 0 (x) = 10 · x4 + 6 · x1
W 0 (2) = 172
Wskazówki: Program składać się ze struktury danych pozwalającej pamiętać
wielomian o współczynnikach całkowitych oraz procedur, które pozwalają na wykonywanie następujących czynności:
1) wczytać wielomian,
2) wyświetlić wielomian w sposób wyżej opisany,
3) Przekształcić informację pamiętaną w odpowiedniej strukturze danych tak,
aby zamiast wielomianu opisywała jego pochodną,
4) obliczanie wartości wielomianu dla danego argumentu całkowitego metodą
Hornera.
Program główny powinien być zbudowany z tych czterech procedur. Przemyśl,
jakie powinny być parametry tych procedur.
Zad. 2. (Zmodyfikowane zadanie nr 4 z listy 1 dr Krupickiej.) Napisz program z
ofertą (menu), który dla danej liczby naturalnej n proponuje następujące usługi
(procedury lub funkcje):
1) sprawdzanie, czy liczba n jest doskonała, tzn. czy jest równa sumie wszystkich jej podzielników mniejszych od niej samej, np. 28=1+2+4+7+14;
2) sprawdzenie, czy n jest liczba pierwszą;
3) podanie rozkadu n na czynniki pierwsze;
4) podanie wszystkich liczb pierwszych nie większych niż n (algorytm sito Eratostenesa).
2
Zadanie to powinno zostać rozwiązane w specyficzny sposób. A więc po pierwsze powinno polegać na utworzeniu jednego lub dwóch modułów (pakietów).
Jeden pakiet mógłby zawierać specjalną implementację sita Eratostenesa. Zwykłe sito można przekszałcić tak, aby nie tylko badało pierwszość liczb z pewnego
przedziału, ale by przy okazji znajdowało największe (lub najmniejsze) dzielniki
analizowanych liczb, będące liczbami pierwszymi. Taki moduł mógłby dodatkowo
zawierać w części inicjalizacyjnej polecenie wykonania algorytmu Eratostenesa, a
pozostałe procedury wymagane w tym zadaniu mogłyby już tylko korzystać z przeprowadzonych obliczeń. Na przykład stwierdzenie, czy dana liczba jest pierwsza
mogłoby polegać zajrzeniu do tablicy utworzonej na początku działania programu.
Potrafię wykorzystać tablicę tworzoną przez zmodyfikowane sito Eratostenesa
we wszystkich usługach wymaganych w zadaniu.
Drugi pakiet mógłby zawierać procedury związane z obsługą samego menu.
Jest spora szansa, że jeżeli będzie dobrze napisany, to przyda się w przyszłości.
Zaprogramowanie wygodne menu wymaga chyba wykorzystania takich funkcji,
jak ReadKey, i takich procedur, jak GotoXY z pakietu crt.
Zad. 3. Zaprogramuj prosty kalkulator.
Idea programu: program korzysta ze struktury danych złożonej z trzech zmiennych: R - zmienna robocza, P - pamięć, D - ostatnie działanie. Początkowo zmienne
R i P pamiętają wartości 0, a D, że ostatnim wprowadzonym działaniem jest dodawanie. Kalkulator reaguje na naciskanie klawiszy z cyframi i kilkoma innymi, np.
+, −, ∗, &, ESC, BackSpace, Enter. Klawisze z cyframi służą do wprowadzania
cyfr, +, −, ∗, & przekazują informacje o wykonywanym działaniu, ESC – kończy działanie programu, BackSpace wymazuje ostatnio wprowadzoną cyfrę. Warto
przewidzieć kilka dalszych czynności, np. zerowanie zmiennej roboczej. Na ekranie,
w określonym miejscu jest wyświetlana wartość zmiennej R. Naciśnięcie klawisza
z cyfrą powoduje zmianę wartości zmiennej roboczej odpowiadającej dopisaniu do
przedstawienia pamiętanej tam liczby cyfry odpoowiadającej wciśniętemu klawiszowi. Analogicznie definiujemy działanie klawisza BackSpace (usuwanie ostatniej
cyfry przedstawienia liczby pamiętanej w R). Wciśnięcie klawisza z symbolem działania powinno spowodować wykonanie pamiętanego działania i odpowiednią zmianę zmiennej P , wyzerowanie zmiennej R i zapamiętanie nowego, wykonywanego w
przyszłości. Wciśnięcie znaku = lub klawisza Enter powinno wykonać ostatnio pamiętane działanie, przedstawienie wyniku w zmiennej R, wyzerowanie zmiennej P ,
zapamiętanie dodawania jako ostatniego działania. Szczegóły działania kalkulatora
być może wymagają jeszcze przemyślenia i pewnych modyfikacji.
Wygodne korzystanie z takiego programu wymaga chyba wykorzystania takich
funkcji, jak ReadKey, i takich procedur, jak GotoXY z pakietu crt.
Zad. 4. Zadanie 3 z listy 1 dr Heleny Krupickiej.
Pytasz kogoś o miesiąc urodzenia. Ile przypadkowo napotkanych osób trzeba
zapytać o miesiąc urodzenia, aby trafić na drugą osobę, która urodziła się w tym
miesiącu?
Przykład: Pierwsza osoba MAR. Kolejne: LUT STY SIE GRU CZE MAR.
Liczba prób: 6.
Zaprogramuj eksperyment losowy, polegający na liczeniu, ile osób trzeba zapytać o miesiąc urodzenia, aby napotkać kogoś, kto urodził się w danym miesiącu.
Program powinien powtórzyć eksperyment 1000 razy oraz czytelnie wypisać przeciętną liczbę prób.
Przykładowy protokół wykonania programu:
Podaj miesiąc urodzenia: MAR. Przeciętna liczba prób dla 1000 doświadczeń wynosi xx.xx.
W tym zadaniu trzeba umieć korzystać z procedur służących do losowego ge-
3
narowania liczb. Jest w nim obliczana metodą Monte Carlo średnia liczba prób
potrzebnych do wylosowania określonego przedmiotu (w tym przypadku: ze zbioru o dwunastu elementach).
Aby zadanie to miało sens na pracowni z Pascala, należy rozwiązać go spełniając niżej podane warunki.
W dialekcie FreePascal można wygodnie wczytywać dane typu wyliczeniowego i przeksztacać je w odpowiednie liczby używając używając obsady zmiennych
(ewentualnie funkcji Ord). Wprowadź więc typ wyliczeniowy Miesiące z elementami nazwanymi jak miesiące i posłuż się np. obsadą zmiennej.
Twój program powinien zawierać cztery procedury:
1) Procedurę Dane, która pobiera od użytkownika nazwę miesiąca.
2) Procedurę Eksperyment pozwalającą na symulowanie pojedyńczego eksperymentu, wykonującą losowanie tak długo, aż zostanie wylosowany dany element. W tej procedurze w naturalny sposób używa się instrukcji repeat.
3) Procedurę Seria symulującej tysiąckrotne wykonanie procedury Eksperyment. Liczba 1000 powinna w Twoim programie być stałą.
4) Procedurę Wynik eksperymentu dokonującej stosownych obliczeń średniej i
informującą o ich wyniku w czytelnej postaci.
Dane i wyniki obliczeń powinny być przekazywane pomiędzy procedurami za
pomocą parametrów, a w treści procedur nie mogą występować zmienne globalne.
Zad. 5. Zadanie podobne do poprzedniego. Obliczyć metodą Monte Carlo liczbę
π. Przedstawić wyniki obliczeń i prawdziwą wartość tej liczby. Aby zrobić to zadanie należy wyobrazić sobie kwadrat jednostkowy. Rysując okrąg o promieniu 1
i środku w lewym dolnym rogu dzielimy ten kwadrat na ćwiartkę koła i resztę.
Aby obliczyć π, wykonujemy serię doświadczeń polegających na losowaniu punktu
z kwadratu. Zliczamy przy okazji, ile razy wylosowaliśmy punkt z ćwiartki koła.
Dzieląc liczbę wylosowanych punktów z ćwiartki koła przez liczbę losowań powinniśmy otrzymać w przybliżeniu π/4. Dla porównania program powinien podawać
przybliżenie wartości π z dokłanością do 6 znaku po przecinku.
Program rozwiązujący to zadanie powinien mieć takie procedury, jak ostatnie
trzy poprzedniego.
Zad. 6. Napisz program, który znajdzie w danej tablicy największy element i drugi
w kolejności (ten element, który po uporządkowaniu danej tablicy znajdzie się tuż
obok największego). Dobry program musi wykonywać mało porównań, mniej niż
półtora n, gdzie n oznacza liczb elementów danej tablicy. Wskazówki dotyczące algorytmu: Drzewo binarne o n liściach można reprezentować w tablicy o elementach
indeksowanych od 0 do 2 ∗ n − 2. Liście znajdują się w elementach indeksowanych
od n − 1 do 2 ∗ n − 2. Lewy i prawy z synów elementu o indeksie i znajdują się w
elementach o indeksach 2∗i+1 i 2∗i+2 odpowiednio. Aby znaleźć największą liczbę w ciągu danych, dane te umieszczamy w liściach pewnego drzewa, a następnie
wypełniamy całe drzewo od liści do korzenia stosując następującą zasadę: jeżeli w
obu elementach potomnych pewnego węzła są umieszczone jakieś liczby, to w tym
węźle umieszczamy większą z liczb. Jeżeli w ten sposób wypełnimy całe drzewo, to
w korzeniu znajdzie się liczba największa. Liczba druga w kolejności musiała być
porównywana z największą. Analizując tak wypełnione drzewo łatwo ustalić, które
dane były porównywane z największą liczbą. Dalej wystarczy jakkolwiek znaleźć
największą z tych danych.
Zad. 7. Napisz program realizujący niżej podany program główny, który dodaje i
mnoży dwuwymiarowe tablice liczb całkowitych o wymiarach n x n (n jest stałą w
4
programie), i który w czytelny sposób przedstawia wyniki, np. drukując elementy
tablic wierszami.
Dodawanie tablic: Sumę C = A + B tablic A i B obliczamy dodając odpowiadające elementy tablic, czyli
C[i, j] = A[i, j] + B[i, j]
dla i, j = 1, 2, . . . , n.
Mnożenie tablic: Iloczyn C = AB tablic A i B obliczamy mnożąc i sumując
odpowiednie elementy tablic, zgodnie ze wzorem
C[i, j] =
n
X
A[i, k] ∗ B[k, j]
k=1
dla wszystkich możliwych i oraz j.
Elementami danych tablic sź losowe liczby naturalne z przedziału [0, 10).
Program główny:
begin
losujTab(a,n);
Writeln(’Wylosowane elementy tablicy:’);
wypiszTab(a,n);
dodajTab(a,a,c,n);
Writeln(’Suma:’);
wypiszTab(c,n);
mnozTab(a,a,c,n);
Writeln(’Iloczyn:’);
wypiszTab(c,n);
mnozTab(a,a,a,n);
Writeln(’Iloczyn:’);
wypiszTab(a,n)
end.
Trudność w tym zadaniu polega na odpowiednim zadeklarowaniu parametrów
procedur tak, aby wyświetlone iloczyny, które zgodnie z naturalnym rozumieniem
programu powinny być takie same, rzeczywiście były takie same.
Zad. 8. Napisz moduł pozwalający na korzystanie z list dwukierunkowych i oblicz metodą Monte Carlo średnią liczbę porównań wykonywanych przez algorytm
sortowania przez wstawianie do listy dwukierunkowej.
Lista dwukierunkowa (potrzebna w tym zadaniu) składa się z rekordów o trzech
polach. W dwóch polach pamiętane są wskaźniki do następnego i do poprzedniego
elementu listy. Trzecie pole zawiera informację przechowaną w tym elemencie listy.
W naszym przypadku może to być wartość typu Integer. W przypadku listy dwukierunkowej, a w przeciwieństwie do listy jednokierunkowej, aby mieć dostęp do
całej listy i informacji zgromadzonej na liście wystarczy znać wskaźnik do jednego,
dowolnego elementu listy.
5
W module powinny się znaleźć procedury pozwalające utworzyć jednoelementową listę dwukierunkową, znaleźć pierwszy element niepustej listy dwukierunkowej,
wyświetlić kolejno wszystkie liczby pamiętane w kolejnych elementach listy, od
pierwszego do ostatniego, i inne (nie wymieniłem bardzo ważnej procedury). Ponieważ mamy sortować przez wstawianie, więc będzie zajmować się niemalejącymi
listami, w których kolejny element jest przynajmniej taki, jak poprzedni. Będzie
też potrzebna procedura pozwalająca wstawić dany element we właściwe miejsce
uporządkowanej listy dwukierunkowej.
Mając taki moduł możemy zaprogramować dwa algorytmy sortowania przez
wstawianie. Sortowane będą losowe ciągi danej długości, generowanych funkcją
Random liczb naturalnych, mniejszych od ustalonej, dość dużej liczby, większej
od długości tworzonych list (im mniejsza będzie ta liczba, tym sortowanie będzie
łatwiejsze). Pierwszy algorytm powinien wstawiać kolejno generowane liczby we
właściwe miejsce tworzonej listy i zostawiać wskaźnik do listy tak, aby pamiętał ostatni wstawiony element. Drugi algorytm ma symulować wstawianie do listy
jednokierunkowej, a więc po wstawieniu do listy kolejnego elementu wskaźnik do
listy powinien zostać cofnięty i wskazywać pierwszy element listy. Oba algorytmy uzupeniamy o liczniki zliczające wykonywane porównania sortowanych liczb.
Wykonując wielokrotnie sortowanie za pomocą takich algorytmów można obliczyć
też średnią liczbę porównań wymaganych przy porządkowaniu n losowych liczb (n
trzeba odpowiednio ustalić).
Średnia liczba porównań wykonywanych podczas sortowania przez wstawianie
2
.
n losowych liczb do listy jednokierunkowej wyraża się wzorem n +n−2
4
Twój program powinien umożliwiać testowanie powyższego wzoru i wyliczać
średnią liczbą porównań wymaganych podczas sortowania przez wstawianie do
listy dwukierunkowej. Zadbaj o to, by działał dobrze dla dość długich list (np.
długości 100) i obliczał średnią liczbę porównań dość dużej liczby sortowań.
Zad. 9. Zaprogramuj wersję obiektową poprzedniego zadania. Wersja obiektowa
też może wykorzystywać moduł, ale rolę modułu z poprzedniego zadania powinien przejąć typ obiektowy Lista dwukierunkowa. Ten typ może być dziedziczony
przez dwa inne typy Lista uporządkowana 1 i Lista uporządkowana 2, które wśród
metod mają dodatkowo procedury sortujące.
Zad. 10. Napisz program, który wykorzystuje trzy typy obiektowe. Pierwszy typ o
nazwie Tablica, który przechowuje tablicę liczb cakowitych, umożliwia wypełnienie
tej tablicy losowymi wartościami oraz pokazanie jej zawartości.
Drugi typ, Tablica uporządkowana dziedziczy komponenty typu Tablica i posiada dodatkowo metodę umożliwiającą sortowanie tablicy. Metoda sortująca (w
jakiś prosty sposób) powinna jednak korzystać z jawnie zdefiniowanej z funkcji
porównaj porównującej dwa elementy tablicy (np. o treści: porwnaj := tab[i] <
tab[j]).
Trzeci typ dziedziczy komponenty typu Tablica uporządkowana i również zawiera metodę porównaj, której treść sprowadza się np. do wykonania podstawienia
porwnaj := tab[i] > tab[j].
Program powinien demonstrować możliwość sortowania tablic zarówno rosnąco,
jak i malejąco za pomocą tej samej procedury sortującej.
Zad. 11. (Zadanie 3.8. z listy pani dr Krupickiej) Pole obszaru zawartego między
krzywą o równaniu y = f (x) i osią Ox w przedziale [a, b] jest równe wartości caki
oznaczonej z funkcji f (x) w tym przedziale. Przybliżoną wartość tej całki (pola)
można obliczyć tzw. metodą trapezów w następujący sposób:
1) Cały obszar dzielimy na pionowe paski, które mają w przybliżeniu kształt
trapezu.
6
2) Obliczamy pole każdego trapezu.
3) Dodajemy do siebie pola wszystkich tak otrzymanych trapezów.
Podaj definicję funkcji calka, której parametrami są: funkcja f , końce przedziału
a i b oraz liczba trapezów n, a wynikiem – całka z funkcji f w przedziale [a, b].
Wyświetl wartości funkcji całka z f w tym przedziale dla różnych (wzrastających)
wartości n. Do testowania wybierz różne funkcje f .
Uwaga1: zakładamy, że z danej funkcji f można obliczyć całkę w podanym
przedziale. Uwaga2: w rozwiązaniu zadania należy wykorzystać typ proceduralny
lub funkcyjny.
Zad. 12. Napisz program sortujący duży plik jednorodny (zawartość pliku to ciąg
danych pewnego rodzaju i zakładamy, że dane tego rodzaju potrafimy porównywać,
np. danymi są liczby naturalne). Dodatkowo zakładamy, że dane z pliku możemy
czytać tylko w najprostszy sposób: po kolei począwszy od początku. Wykorzystaj
jeden z niżej podanych algorytmów.
Algorytm 1. Zakładamy, że dany plik jest podzielony na fragmenty tej samej
długości, poprawnie uporządkowane. Bezpośrednio po uruchomieniu te fragmenty
mają długość 1, później długość fragmentów będzie się podwajać. Ostatni fragment może być niepełny. Najpierw dany plik dzielimy na dwa pliki zawierające
w przybliżeniu tyle samo fragmentów. Następnie, scalamy kolejne fragmenty obu
plików (n-ty fragment pierwszego pliku scalamy z n-tym fragmentem drugiego)
zapisując efekt scalania do trzeciego pliku. Te czynności powtarzamy, aż cały plik
zostanie uporządkowany.
Algorytm 2. Jest podobny do algorytmu 1, wymaga scalania fragmentów różnej
długości. Każdy plik w naturalny sposób dzieli się na tzw. serie, czyli maksymalne,
poprawnie uporządkowane fragmenty. Dany plik dzielimy na dwie części i scalany –
podobnie jak w poprzednim algorytmie – kolejne serie, powtarzając te czynności aż
do skutku. Możemy zliczać zapisywane serie i na podstawie ich liczby decydować o
zakończeniu pracy algorytmu. Algorytm może się zapętlić, jeżeli będziemy dzielić
plik w zbyt prosty sposób, np. na pół. W tym przypadku dojdzie do zapętlenia,
jeżeli pierwsza seria zajmuje więcej niż połowę pliku i zostanie podzielona.
Zad. 13. (Prymitywna baza danych.) Napisz program, który dostaje w pliku tekstowym dostaje informacje o osobach, zapisuje te informacje w pamięci komputera
i umoliwia operowanie tymi informacjami, oraz zapisuje zgromadzone informacje
w pliku jednorodnym.
Szczegóły programu: Dane o osobach są zapisane w pliku tekstowym. O tym
pliku zakadamy, że w każdej linii zawiera informację o jednej osobie, informacja ta
składa się przynajmniej z trzech części: imienia, nazwiska i roku urodzenia. Imię i
nazwisko składają się wyłącznie z liter, rok urodzenia to ciąg cyfr. Te trzy części
są oddzielone od siebie (i ewentualnie od reszty linii) spacjami, spacje mogą też
znajdować się przed imieniem i po roku urodzenia. W imieniu i nazwisku mogą
być pomieszane litery dowolnej wielkości.
Dane w pamięci komputera są przechowywane wyłącznie w drzewie bst, a w
pamięci zewnętrznej – w pliku jednorodnym. Imię i nazwisko w drzewie bst są
pamiętane w postaci ujednoliconej (zaczynają się dużą literą, po której są litery
małe). Wśród danych o osobie (w drzewie i pliku jednorodnym) jest też informacja
o płci ustalana na podstawie ostatniej litery imienia.
Program powinien symulować obsługę bazy danych i umożliwiać (wielokrotne)
wykonanie następujących czynności:
1) wczytanie danych z pliku tekstowego, a także dopisanie pojedyńczej informacji o osobie (do istniejącego lub nie drzewa bst),
7
2) zapisywanie informacji o osobach w pliku jednorodnym, w kolejności alfabetycznej,
3) wyświetlenie zawartości pliku tekstowego, a także informacji zgromadzonej
w drzewie bst oraz w odpowiednim pliku jednorodnym.
Program powinien kontrolować istnienie pliku z danymi, a także poprawność
danych zapisanych w pliku (czy imię i nazwisko składają się liter, a rok urodzenia
jest liczbą oddzieloną od ewentualnych dalszych informacji przynajmniej jedną
spacją, np. napis ’2011.’ nie jest poprawnym rokiem urodzenia).
Antoki Kościelski