Dane: liczba / w systemie dziesiętnym, podstawa systemu p. xi = f%/2) = 0.0015 = 1.500 10~3.
Wynik: zapis liczby Z w systemie o podstawie p.
1. Czytaj liczby lip.
2. Dopóki I > 0 powtarzaj krok 3.
3. Wykonaj dzielenie całkowite liczby / przez p, resztę z dzielenia zapamiętaj
jako kolejną cyfrę przedstawienia liczby Z w nowym systemie pozycyjnym,
4. Drukuj cyfry przedstawienia liczby I w nowym systemie pozycyjnym w od-
wrotnej kolejności niż były zapamiętywane.
Wskazówka: Cyfry przedstawienia liczby w nowym systemie pozycyjnym umie-
szczaj w tablicy. Wystarczy użyć tablicy o rozmiarze 16, gdyż z tylu cyfr składa
się zapis w systemie dwójkowym największej liczby całkowitej typu INTEGER
(32767).
4.10. Połącz możliwości programów SredniaOcen z p. 4.4.1 i Najlepsi z p. 4.4.2
tak, aby średnia ocen nie była wczytywana z klawiatury, ale obliczana w progra-
mie. Wymaga to oczywiście wprowadzenia ocen z poszczególnych przedmiotów
dla każdego ucznia. Zmień ponadto opis procedury Szukaj Najlepszych (z przy-
kładu 4.20) tak, aby można było wyszukiwać uczniów ze średnią ocen należącą
do przedziału podanego przez użytkownika (np. poniżej 3.5, między 4.0 a 4.5).
4.11. Rozbuduj rekord typu Uczeń z p. 4.4.2, dopisując pole służące do pamię-
tania ocen z poszczególnych przedmiotów. Dla tak zmienionej struktury danych
napisz procedury:
- Drukuj Średnie, która drukuje nazwiska uczniów i średnie ich ocen zgodnie
z życzeniem użytkownika (wszystkie średnie lub tylko z wybranego prze-
działu);
- Drukuj Świadectwo, która drukuje świadectwo, czyli wykaz wszystkich ocen
danego ucznia;
- ObliczZestawienie, która oblicza zestawienie ocen dla każdego z przed- ,
miotów, tzn. liczy ile ocen celujących, bardzo dobrych, dobrych, dostatecz-l
nych, miernych i niedostatecznych uzyskali uczniowie z danego przedmiotu.
Umieść w odpowiednim miejscu w programie definicję i wywołanie poniższej |
procedury Oferta umożliwiającej wybór jednej z dostępnych możliwości.
Zadania
157
PROCEDURĘ Oferta;
VAR OdprINTEGER;
BEGIN
WRITELN('l. Drukowanie nazwisk i średnich ocen uczniów.');
WRITELNC2. Drukowanie świadectwa wybranego ucznia.');
WRITEC3. Drukowanie zestawienia ocen z poszczególnych ');
WRITELN('przedmiotów.');
WRITELN('4. Zakończenie pracy.');
WRITELN;
WRITE('Wybierz numer opcji: ');
READLN(Odp);
CASE Odp OF
1:DrukujŚrednie;
2:DrukujŚwiadectwo;
3:ObliczZestawienie;
4:;
ELSE Oferta
END; -CCASE}
Koniec;
IF Odp<>4 THEN Oferta
END; {Oferta}
Uwaga: Tekst procedury Oferta znajduje się na dyskietce w pliku OFERTA.PAS umie-
szczonym w kartotece ROZDZ4.
W procedurze Oferta, jeśli wartość zmiennej Odp jest różna od wartości
wymienionych przed dwukropkami, to jest wykonywana instrukcja umieszczona
po słowie kluczowym ELSE, czyli następuje rekurencyjne wywołanie procedury
Oferta. Jeśli 0dp=4, to jest wykonywana instrukcja pusta, a instrukcje następu-
jące po instrukcji CASE spowodują albo zakończenie pracy programu, albo powrót
do oferty programu w przypadku wybrania opcji o numerze od 1 do 3.
4.12. Zaproponuj definicję typu wskaźnikowego dla listy reprezentującej ciąg liczb
rzeczywistych dowolnej długości.
4.13. Zmodyfikuj procedurę Czytaj ImNazw z p. 4.5 tak, aby tworzona lista ucz-
niów była uporządkowana alfabetycznie według nazwisk.
4.14. Napisz procedurę, która usuwa z listy rekord z danymi ucznia o podanym
nazwisku.
Wskazówka: Procedura powinna działać poprawnie także wtedy, gdy lista jest
pusta lub, gdy jest usuwany ostatni uczeń z listy lub, gdy na liście nie ma ucznia
o podanym nazwisku.
i
i
5. ZAKŁADAMY WŁASNY KATALOG -
BAZY DANYCH
5.1. Zakładamy bazę danych. Pliki
Komputery umożliwiają przetwarzanie dużych ilości informacji przechowywanych
w postaci zbiorów danych w pamięci zewnętrznej. Zbiór zawierający dane o ok-
reślonej strukturze nazywa się bazą danych. Wiele zbiorów informacji z naszego
otoczenia odpowiada ogólnemu pojęciu bazy danych, na przykład: dziennik lek-
cyjny (zob. rozdz. 4), książka adresowa, zbiór rachunków za światło, katalog bi-
blioteczny, wykaz części zamiennych, spis pracowników w przedsiębiorstwie itd.
(por. zad. 5.1). Celem, dla którego tworzy się bazy danych w pamięci kompu-
terów, jest chęć uzyskania szybkiego dostępu do informacji w nich zapamiętanych.
Wykonywanie operacji na bazach danych ułatwia odpowiednia organizacja zawar-
tych w nich informacji.
Najmniejszym elementem, który wchodzi w skład bazy danych, jest rekord,
czyli zbiór danych tworzących logiczną całość. Każda dana zajmuje w rekordzie j
określone miejsce zwane polem. W języku Pascal takiemu elementowi odpowiada j
zmienna typu rekordowego.
Końcowy efekt przetwarzania bazy danych można wyrazić jako złożenie wszy- j
stkich lub niektórych z następujących operacji:
- wyszukiwanie i odczytywanie rekordów,
- aktualizacja (modyfikacja) zawartości istniejących rekordów,
- dołączanie (zapisywanie) nowych rekordów do bazy danych,
- usuwanie rekordów z bazy danych.
Zajmiemy się utworzeniem własnej bazy danych w komputerze. Będzie to I
katalog książek znajdujących się w naszym księgozbiorze. Przyjmijmy, że pod-1
stawowa informacja dotycząca pojedynczej książki składa się z nazwiska i imienia|
autora oraz tytułu książki. Dodatkowo chcemy również wiedzieć, czy wypoży-
czyliśmy tę książkę komuś, czy też znajduje się ona na naszej półce. Informację!
5.1. Pliki
159
dotyczącą książki zapiszemy w postaci rekordu złożonego z trzech pól. Oto jego
definicja w języku Pascal.
Przykład 5.1. Księgozbiór opisano jako plik elementów typu Książka:
TYPE Napis30 =STRING [30];
Napis50 =STRING[50];
Książka =REC0RD
Autor:Napis30;
Tytuł:Napis50;
Jest :B00LEAN
END;
Ksiegozbior=FILE 0F Książka;
VAR Katalog:Księgozbiór; -[zmienna odpowiadająca naszemu
księgozbiorowi}
Egz :Ksiazka; {reprezentacja pojedynczej książki}
Uwaga: Tekst powyższych definicji typów i deklaracji zmiennych znajduje się na dys-
kietce w pliku TYPY.PAS umieszczonym w kartotece R0ZDZ5.
Plik w języku Pascal jest strukturą danych, która podobnie jak tablica,
składa się z elementów tego samego typu (w przykładzie 5.1 są to elementy typu
Książka). W przeciwieństwie do tablicy, w której liczba elementów jest z góry
określona w odpowiedniej deklaracji, w przypadku pliku nie ma ograniczenia na
liczbę jego elementów. Wynika stąd, że plik jest znacznie wygodniejszy od ta-
blicy w sytuacjach, gdy nie potrafimy z góry przewidzieć, z jaką liczbą elementów
będziemy mieli do czynienia. W zasadzie plik jest strukturą danych o dostępie
sekwencyjnym1. Oznacza to, że elementy w niepustym pliku są dostępne po
kolei, w danej chwili co najwyżej jeden element.
W programach w języku Pascal możemy korzystać ze standardowego typu
plikowego TEXT, zwanego tekstowym. Niepuste pliki tekstowe składają się z se-
kwencji wierszy, a wiersze są podzielone na znaki.
W tym rozdziale termin plik oznacza zmienną plikową w systemie Turbo Pa-
scal, czyli zmienną typu plikowego. Natomiast plik w znaczeniu podanym w roz-
dziale 2 (por. p. 2.5) nazywamy tutaj plikiem fizycznym. Plik na ogół reprezen-
tuje dane przechowywane na dysku. W przeciwieństwie do danych pamiętanych
np. w tablicach czy w listach, dane zapamiętane w pliku fizycznym na dysku są
dostępne nie tylko w czasie działania programu, ale np. przy powtórnym jego
uruchomieniu i mogą z nich korzystać również inne programy.
Napisaliśmy "w zasadzie", gdyż w standardowej wersji języka Pascal pliki są właśnie tak
traktowane. Można jednak spotkać pewne odstępstwa od tej zasady, np. w systemie Turbo Pascal
do elementów pliku można się odwoływać poprzez numery miejsc jakie zajmują. W przykładach
przedstawionych w tym rozdziale nie ma jednak potrzeby korzystania z tej możliwości.
160
5. Bazy danych
Przed pierwszym użyciem pliku w programie musi być wywołana procedura
ASSIGN, na przykład
ASSIGN(Katalog,NazwaPliku)
w której pierwszy parametr jest zmienną plikową, a drugi - jest wyrażeniem
napisowym. W wyniku wykonania powyższej instrukcji zmienna Katalog zo-
stanie skojarzona z fizycznym plikiem o nazwie określonej wartością parame-
tru NazwaPliku. Od tej chwili każda operacja wykonana w programie na pliku
Katalog odnosi się do fizycznego pliku NazwaPliku.
Jeśli przenosimy informacje do (lub z) pliku, to nazwę tego pliku umie-
szczamy jako pierwszy parametr procedury WRITE (lub READ), a następnymi pa-
rametrami są nazwy zmiennych takiego samego typu jak elementy pliku, np.
WRITE (Katalog, Egz). Z podobnym użyciem procedury WRITE spotkaliśmy się
już w p. 4.1, gdzie pierwszy parametr procedury oznaczał plik związany z dru-
karką (zob. także p. 2.5).
Przetwarzanie plików w programie odbywa się według jednolitego schematu
opisanego w następującym algorytmie.
Algorytm 5.1. Przetwarzanie pliku w programie.
1. Zwiąż plik w programie z plikiem fizycznym za pomocą procedury ASSIGN,
np. ASSIGN(Katalog,NazwaPliku).
2. Otwórz plik do odczytu lub zapisu. Odpowiednie czynności wykonuje proce-
dura RESET lub REWRITE, np. REWRITE(Katalog) - procedury te są opisane
w punkcie 5.2.
3. Następnie są wykonywane operacje odczytu lub zapisu elementów pliku za
pomocą procedur READ i WRITE (a także READLN i WRITELN w przypadku
plików tekstowych; por. p. 4.2), np. WRITE(Katalog,Egz).
4. Zamknij plik za pomocą procedury CLOSE, np. CLOSE(Katalog).
Na końcu każdego pliku definiowanego w tym rozdziale umieszczamy ele-
ment zawierający w wyróżnionym polu specjalną wartość różną od wartości znaj-
dujących się w tym polu we wszystkich pozostałych elementach pliku. Taki
element nazywamy powszechnie wartownikiem (dalej, tego terminu używamy
również dla oznaczenia tej specjalnej wartości). Wartownik ułatwia na ogół roz-
poznawanie końca danych - korzystamy z tego w procedurze PrzetwPliki. Dla
zachowania jednolitości opisów algorytmów w kolejnych przykładach, związanych
z tworzeniem i modyfikowaniem księgozbioru, stosujemy wartownika już od sa-
mego początku zakładania bazy.
Przykład 5.2. Napiszemy teraz program, który zapisuje informacje o naszym
księgozbiorze w pliku Katalog. Dane będziemy wprowadzać z klawiatury, a ko-
munikaty o wykonywanych operacjach będą wyświetlane na ekranie monitora.
5.1. Pliki
161
Program2 TworzeniePliku zakłada plik opisów książek. Ponieważ w kodzie
ASCII najpierw występują wszystkie wielkie, a później wszystkie małe litery al-
fabetu łacińskiego, dlatego za wartownika przyjmujemy napis 'zz'. Zakładamy
ponadto, że nazwiska autorów i tytuły książek będą pisane tylko wielkimi albo
tylko małymi literami alfabetu łacińskiego. Dzięki temu można łatwo sprawdzać
alfabetyczną kolejność ciągu znaków (napisu) stosując relację np. <. Gdybyśmy
chcieli używać jednocześnie małych i wielkich liter, to należałoby zmodyfikować
ten i następne programy wprowadzając porównywanie napisów znak po znaku.
W programach zamieszczonych w tym rozdziale korzystamy z procedur Start
i KojarzeniePliku. Procedura Start wyświetla informacje o programie, które
podajemy w jej wywołaniu jako parametr aktualny. Oto opis tej procedury:
PROCEDURĘ Start(Nagłówek:STRING);
BEGIN
CLRSCR;
WRITE(Nagłówek);
WRITELN; WRITELN
END; {Start}
Procedura KojarzeniePliku kojarzy plik z plikiem fizycznym. Przyjmujemy,
że nazwę pliku fizycznego będzie podawał użytkownik po wyświetleniu przez pro-
gram odpowiedniego komunikatu.
PROCEDURĘ KojarzeniePliku(VAR Plik:Księgozbiór;
OpisPliku:STRING);
-[Procedura kojarzy zmienna Plik z plikiem fizycznym
(NazwaPliku) w pamięci zewnętrznej. Nazwa pliku fizycznego
jest podawana przez użytkownika.}
VAR NazwaPliku:STRING;
BEGIN
{Wartością napisu 'Podaj ... reprezentującego '+ OpisPliku
jest ciąg znaków: Podaj ... reprezentującego , po którym
występuje ciąg znaków będących wartością zmiennej OpisPliku.
Znak dodawania + oznacza tutaj konkatenacje (czyli łączenie)
dwóch napisów, polegająca na dopisaniu drugiego bezpośrednio
po pierwszym.}
WRITELN('Podaj nazwę pliku fizycznego reprezentującego '
+ OpisPliku +'.');
W programach nie umieszczono, występującego w profesjonalnych systemach baz danych,
badania poprawności danych wprowadzanych przez użytkownika. Dodanie takiej kontroli wy-
magałoby znacznego rozbudowania programów, co utrudniałoby śledzenie istotnych czynności
związanych z tworzeniem baz danych, które chcemy zilustrować w tym rozdziale.
i Elementy informatyki
162
5. Bazy danych
READLN(NazwaPliku);
ASSIGN(Plik,NazwaPliku)
END; {KojarzeniePliku}
Uwaga: Teksty procedur Start i KojarzeniePliku są umieszczone na dyskietce w pro-
gramie TworzeniePliku, który znajduje się w pliku TWÓRZ.PAS w kartotece R0ZDZ5.
Przykładowo, po wywołaniu procedury
KojarzeniePliku(Katalog,'książki')
jest wyświetlany napis:
Podaj nazwę pliku fizycznego reprezentującego książki.
i program oczekuje na podanie przez użytkownika nazwy odpowiedniego pliku fi-
zycznego. Wprowadzona nazwa staje się wartością zmiennej NazwaPliku i zostaje
wykorzystana w instrukcji ASSIGN(Plik.NazwaPliku).
Zapamiętajmy, że w systemie Turbo Pascal parametry typu plikowego mogą
być przekazywane tylko przez zmienną, dlatego w nagłówku procedury muszą
być poprzedzone słowem kluczowym VAR. Poniższy program tworzy plik z infor-
macjami o książkach.
PROGRAM TworzeniePliku;
USES CRT;
CONST Wartownik='zz';{ostatni element w porządku alfabetycznym}
TYPE Napis30 =STRING [30];
Napis50 =STRING[50];
Książka =REC0RD
Autor:Napis30;
Tytuł:Napis50;
Jest :B0DLEAN
END;
Ksiegozbior=FILE 0F Książka;
VAR Katalog:Księgozbiór; {zmienna odpowiadająca naszemu
księgozbiorowi}
Egz :Książka; {reprezentacja pojedynczej książki}
{Tutaj należy umieścić opisy procedur Start i KojarzeniePliku
omówionych w tym punkcie oraz opis procedury Koniec
z przykładu 4.3.}
BEGIN {Program glowny}
Start('Program tworzy plik opisów książek.');
KojarzeniePliku(Katalog,'Katalog');
5.1. Pliki
163
{otwarcie pustego pliku do zapisu}
REWRITE(Katalog);
{dołączanie informacji katalogowych}
WRITEOAUTOR: '); READLN(Egz.Autor);
WHILE Egz.Autor
Egz.Jest:=TRUE;
{Dane o kolejnej książce umieszczamy w pliku Katalog.}
WRITE(Katalog.Egz);
WRITE('AUTOR: '); READLN(Egz.Autor)
END; {Egz.Aut or
Egz.Aut or:=Wart ownik;
Egz.Tytuł: = " ;
Egz.Jest:=FALSE;
WRITE(Katalog,Egz);
{zamkniecie pliku}
CLOSE(Katalog);
WRITELNO Koniec tworzenia katalogu.');
Koniec
END. {TworzeniePliku}
Uwaga: Tekst programu TworzeniePliku znajduje się na dyskietce w pliku TWÓRZ.PAS fj~\
umieszczonym w kartotece R0ZDZ5.
Przykłady, które ilustrują działanie tego i następnych programów oraz proce-
dur z tego rozdziału umieszczono w rozwiązaniach zadań (zob. EI-II).
Po uruchomieniu programu TworzeniePliku najpierw musimy podać naz-
wę pliku fizycznego znajdującego się w pamięci komputera, w którym ma być
zapisany tworzony katalog. Następnie możemy wprowadzać dane o kolejnych
książkach: po ukazaniu się na ekranie napisu AUTOR: podajemy nazwisko i imię
autora, a po pojawieniu się napisu TYTUŁ: piszemy tytuł książki. Jeśli chcemy
zakończyć wprowadzanie danych, to podajemy jako nazwisko autora ciąg liter zz,
który jest interpretowany przez program jako zakończenie tworzenia katalogu.
Napiszemy teraz procedurę, która wyświetla zawartość pliku. W przypadku
odczytywania zawartości elementów pliku należy w programie wykonać najpierw
instrukcję
RESET (nazwa-zmiennej-plikowej)
która powoduje otwarcie dostępu do pierwszego elementu pliku. Przed wyko-
naniem tej instrukcji, jak już zaznaczyliśmy, plik musi być skojarzony z plikiem
fizycznym, który w tym przypadku musi istnieć.
164
5. Bazy danych
Przykład 5.3. Procedura wyprowadzania elementów pliku.
PROCEDURĘ DrukEcho(VAR DanyPlik:Księgozbiór);
{Procedura czyta i wyświetla kolejne elementy z pliku
DanyPlik.}
VAR El:Książka;
BEGIN
{Skojarzenie pliku DanyPlik z plikiem fizycznym w pamięci
zostanie wykonane w treści programu.}
RESET(DanyPlik);
WRITELN;
{przetwarzanie kolejnych elementów pliku}
READ(DanyPlik,El);
WHILE El.Autor
READ(DanyPlik,El)
END; {WHILE}
WRITELN
END; {DrukEcho}
Uwaga: Tekst procedury DrukEcho znajduje się na dyskietce w pliku DRUKECHO.PAS
umieszczonym w kartotece R0ZDZ5.
Opis procedury DrukEcho możemy umieścić w programie TworzeniePlikul
(z przykładu 5.2) po deklaracjach zmiennych, a instrukcję
DrukEcho(Katalog)
umieścimy wówczas bezpośrednio przed instrukcją CLOSE (Katalog). Wykonanie I
tak zbudowanego programu spowoduje najpierw utworzenie pliku Katalog, a nas-
tępnie wyświetlenie jego zawartości na ekranie. Ponadto na dysku (w pamięci]
zewnętrznej) pozostanie plik fizyczny (por. p. 2.5) z wpisanymi danymi.
Jeśli zawartość pliku ma być wyprowadzona na drukarkę, to instrukcje dru-J
kowania, występujące w procedurze DrukEcho, muszą zawierać jako pierwsz
parametr nazwę pliku skojarzonego z drukarką (por. p. 4.1). W tym przy-J
padku możemy skorzystać ze standardowego w systemie Turbo Pascal moduli
PRINTER3, który zawiera zmienną plikową LST. Zmienna ta jest skojarzona z dru-l
karką (czyli drukarka jest traktowana jak plik) i wykonywana jest dla niej in-J
strukcja równoważna w skutkach z instrukcją REWRITE(LST). Zatem w procedu-j
rze DrukEcho instrukcje wyprowadzania wartości elementów pliku na drukark|
powinny mieć postać:
3Wtedy w programie wiersz z deklaracjami użycia pakietów, który znajduje się bezpośredni^
po nagłówku, musi mieć postać: USES CRT,PRINTER;
ł
5.2. CO JUZ WIEMY O PLIKACH
165
WRITELN(LST,El.Aut or,', ',El.Tytul);
WRITELN(LST)
Wartości zmiennych typu rekordowego nie można w całości wyprowadzać ani
na ekran, ani na drukarkę. Możemy wyprowadzać jedynie wartości typu INTEGER,
REAL, CHAR, BOOLEAN i STRING. Dlatego w procedurze DrukEcho zawartości pól
Autor oraz Tytuł są wyprowadzane osobno. Opis procedury DrukEcho można
dostosować do wyprowadzania zawartości plików złożonych z elementów któregoś
z tych typów. W tym celu należy zmienić typ zmiennej plikowej DanyPlik na
typ plikowy, którego wartości nas interesują i ponadto powinna zostać zmieniona
postać instrukcji WHILE. Jeśli rozważany przez nas plik zawiera elementy np. typu
INTEGER, to odpowiednia instrukcja WHILE może mieć postać:
WHILE NOT EOF(DanyPlik) DO BEGIN
READ(DanyPlik,El);
WRITELN(El) {lub WRITELN(LST,El)>
END; {WHILE}
Parametr El w powyższym fragmencie programu powinien mieć typ taki sam
jak elementy pliku DanyPlik. Standardowa funkcja EOF (DanyPlik) przyjmuje
wartość TRUE, jeśli został już przeczytany ostatni element z pliku DanyPlik (lub
plik jest pusty), a FALSE - w przeciwnym razie.
Jeśli po wyprowadzeniu informacji na ekran (lub drukarkę) nie będziemy już
chcieli korzystać z zawartości pliku fizycznego skojarzonego z plikiem DanyPlik,
to możemy go usunąć za pomocą procedury standardowej ERASE. Wystarczy wy-
konać instrukcję ERASE (DanyPlik).
5.2. Co już wiemy o plikach
Zbierzmy podane dotychczas informacje o plikach. Język Pascal zawiera standar-
dowy typ plikowy TEXT. Typ plikowy możemy również zdefiniować w następujący
sposób:
nazwa-typu-plikowego = FILE OF typ-elementów
Wszystkie elementy pliku muszą być tego samego typu określonego przez
typ-elementów. Typ typ-elementów nie może być ani typem plikowym, ani innym
typem (np. rekordowym) o składowych typu plikowego.
Operacje na plikach wykonujemy wyłącznie za pomocą procedur. Standar-
dowe operacje są realizowane za pomocą następujących instrukcji procedur:
Instrukcja
kSSIGHH (nazwa-zmiennej-plikowej, nazwa-pliku-fizycznego)
166
5. Bazy danych
kojarzy plik reprezentowany przez nazwa-zmiennej-plikowej z plikiem fizycznym
nazwa-pliku-fizycznego. Plik fizyczny nie musi istnieć. Od chwili wykonania tej
instrukcji każda operacja na pliku nazwa-zmiennej-plikowej dotyczy pliku fizycz-
nego nazwa-pliku-fizycznego.
Instrukcja
REWRITE (nazwa-zmiennej-plikowej)
otwiera pusty plik nazwa-zmiennej-plikowej bez względu na to czy istnieje plik i
fizyczny skojarzony z tą zmienną (jeśli taki plik istnieje, to najpierw zostaje
usunięty). Przed wykonaniem tej instrukcji plik o nazwie nazwa-zmiennej-plikowej
musi być skojarzony z plikiem fizycznym (zgodnie z algorytmem 5.1).
Instrukcja
RESET (nazwa-zmiennej-plikowej)
przygotowuje (otwiera) plik nazwa-zmiennej-plikowej do czytania. W tym przy-
padku musi istnieć skojarzony z nim (za pomocą instrukcji ASSIGN) plik fizyczny.
Jeśli nie istnieje, to jest sygnalizowany błąd. Bezpośrednio po otwarciu, plik zo-
staje ustawiony w pozycji początkowej i jest dostępny jego pierwszy element (jeśli
plik nie jest pusty).
Instrukcja
WRITE (nazwa-zmiennej-plikowej, nazw a-zmiennej)
powoduje dołączenie wartości zmiennej nazwa-zmiennej do pliku nazwa-zmien-
nej-plikowej. Parametr nazwa-zmiennej powinien być tego samego typu co typ
elementów pliku nazwa-zmiennej-plikowej. Jeśli plik nazwa-zmiennej-plikowej
jest plikiem tekstowym lub brak jest pierwszego parametru, to nazwa-zmiennej
może zostać zastąpiona przez wyrażenie (lub ciąg wyrażeń oddzielonych przecin-
kami) arytmetyczne, logiczne lub napisowe. W tym drugim przypadku wartość
wyrażenia (wyrażeń) jest wyprowadzana na ekran monitora.
Instrukcja
READ (nazwa-zmiennej-plikowej, nazw a-zmiennej)
przypisuje zmiennej określonej parametrem nazwa-zmiennej bieżący element pliku
nazwa-zmiennej-plikowej. Jeśli po odczytanym elemencie w pliku są jeszcze ja-
kieś elementy, to następny element staje się elementem bieżącym. Parametr naz-
wa-zmiennej powinien być tego samego typu co elementy pliku. Jeśli plik naz-
wa-zmiennej-plikowej jest plikiem tekstowym lub brak jest pierwszego parametru,
to parametr nazwa-zmiennej może być typu logicznego, napisowego lub liczbo-
wego. Brak pierwszego parametru w powyższej instrukcji procedury oznacza |
wprowadzanie danych z klawiatury.
5.3. Aktualizacja bazy danych
167
Instrukcja
ERASE(pHfc)
powoduje usunięcie pliku fizycznego skojarzonego ze zmienną plik.
Instrukcja
CLOSE (nazwa-zmiennej-plikowej)
powoduje zamknięcie pliku nazwa-zmiennej-plikowej otwartego do zapisywania
lub odczytywania i zapewnia, że odpowiadający mu plik fizyczny ma właściwą
postać.
Wyrażenie logiczne
EOF (nazwa-zmiennej-plikowej)
przyjmuje wartość TRUE, jeśli został przeczytany ostatni element z pliku na-
zwa-zmiennej-plikowej lub jeśli plik jest pusty, a wartość FALSE - w przeciwnym
razie.
5.3. Aktualizacja bazy danych
Załóżmy, że w bazie danych Katalog, zawierającej informacje o naszym księgo-
zbiorze, zapisaliśmy już wszystkie książki. Po pewnym czasie stwierdzamy, że na
przykład:
- musimy wprowadzić poprawki, ponieważ zrobiliśmy błędy w pisowni tytu-
łów i nazwisk autorów;
- nasz księgozbiór został powiększony o nowe pozycje;
- chcemy sprawdzić, czy jakaś konkretna książka znajduje się w naszym księ-
gozbiorze;
- niektóre książki nie są naszą własnością (pożyczyliśmy je) i musimy je
zwrócić.
Często zachodzi potrzeba znalezienia w bazie danych jednego lub wielu re-
kordów o określonych własnościach. Łatwiej przeszukuje się bazę, której rekor-
dy są w pewien sposób uporządkowane. Rekordy w bazie danych są na ogół
uporządkowane na podstawie wartości wybranego pola (lub pól) rekordu. Wtedy
pole to nosi nazwę klucza, a o całej bazie mówimy, że jest uporządkowana według
określonego klucza.
Przykład 5.4. Otrzymaliśmy nowe książki i wpisaliśmy nazwiska ich autorów
oraz tytuły w porządku alfabetycznym do nowego pliku Nabytki. Chcemy te
książki dołączyć do naszego księgozbioru. Dla uproszczenia załóżmy, że książ-
ki z księgozbioru znajdują się w katalogu także w porządku alfabetycznym (por.
168
5. Bazy danych
zad. 5.2). Pola Autor i Tytuł stanowią klucz, według którego będziemy przeszu-
kiwać starą i nową bazę danych, czyli księgozbiór i plik z otrzymanymi książkami.
Założymy ponadto, że na końcu każdego z obu plików umieściliśmy wartownika
(por. przykład 5.2). Zatem ostatni rekord każdego pliku w polu Autor ma wpisany
ciąg złożony z liter zz, który można uznać za ostatnie "nazwisko" w alfabetycz-
nym spisie autorów. Dalej w rozdziale zakładamy, że pliki są uporządkowane jak
wyżej. Porządkowanie plików omawiamy w rozwiązaniu zadania 5.2 (zob. EI-II),
a także w rozdziale 7.
Algorytm 5.2. Łączenie uporządkowanych plików.
1. Przygotuj pliki Katalog i Nabytki do czytania informacji w nich zawar-
tych, a plik NowyKatalog - do zapisywania w nim kolejnych elementów
uaktualnianego katalogu.
2. Połącz (scal) pliki Katalog i Nabytki w jeden plik NowyKatalog.
Program realizujący algorytm 5.2 może mieć postać:
PROGRAM Polacz;
USES CRT;
{Program laczy pliki Katalog i Nabytki tworząc skorygowany
plik NowyKatalog.}
CONST Wartownik='zz';{ostatni element w porządku alfabetycznym};1
{Tutaj należy umieścić wszystkie definicje typów z przykła-
du 5.1.}
VAR Katalog,Nabytki,NowyKatalog:Księgozbiór;
{Tutaj należy umieścić opisy procedur Start i KojarzeniePliku
z przykładu 5.2, opis procedury Koniec z przykładu 4.3 i po-
dany w przykładzie 5.5 opis procedury Lacz.}
BEGIN
Start('Program laczy zawartość plików Katalog i Nabytki.');
KojarzeniePliku(Katalog,'Katalog');
KojarzeniePliku(Nabytki,'Nabytki');
KojarzeniePliku(NowyKatalog,'NowyKatalog');
{otwarcie plików}
RESET(Katalog);
RESET(Nabytki);
REWRITE(NowyKatalog);
{połączenie plików Katalog i Nabytki}
Lacz(Katalog,Nabytki,NowyKatalog);
{zamkniecie plików}
CLOSE(Katalog); CLOSE(Nabytki);
CLOSE(NowyKatalog);
5.3. Aktualizacja bazy danych
169
WRITELN('Zakończono łączenie plików Katalog i Nabytki.');
Koniec
END. {Polacz}
Uwaga: Tekst programu Polacz znajduje się na dyskietce w pliku POLACZ.PAS umie-
szczonym w kartotece R0ZDZ5.
Przykład 5.5. Opiszemy teraz szczegółową realizację kroku 2 algorytmu 5.2,
czyli jak działa procedura Lacz.
Algorytm 5.3. Scalanie plików.
1. Przeczytaj pierwszy element z pliku Katalog oraz pierwszy element z pliku
Nabytki.
2. Porównaj bieżące elementy z obu plików, czyli ich pola zawierające nazwiska
autorów i tytuły książek, a następnie:
- skopiuj do pliku NowyKatalog element o kluczu alfabetycznie wcześ-
niejszym;
- przeczytaj informacje dotyczące kolejnej książki z pliku zawierającego
skopiowany element;
- powtarzaj ten krok, aż dojdziesz do końca obu plików, czyli do war-
towników.
3. Skopiuj wartownika do pliku NowyKatalog.
Realizacja kroku 2 może mieć następującą postać:
WHILE (StaraKsiazka.Autor
(NowaKsiazka.Autor+NowaKsiazka.Tytuł) THEN
skopiuj StaraKsiazka do pliku NowyKatalog
i przeczytaj następny element z pliku Katalog
ELSE
skopiuj NowaKsiazka do pliku NowyKatalog
i przeczytaj następny element z pliku Nabytki
Możemy już teraz podać pełny opis procedury Lacz, która ma trzy parametry
typu plikowego. Przypominamy, że w systemie Turbo Pascal parametry tego ty-
pu są zawsze przekazywane przez zmienną (por. p. 5.1). Dlatego w nagłówku
procedury poprzedzono je słowem kluczowym VAR.
PROCEDURĘ Lacz(VAR Plik,Nabytki,NowyPlik:księgozbiór);
{Procedura laczy niepuste uporządkowane pliki Plik
i Nabytki w jeden plik NowyPlik, także uporządkowany.
Zmienne StaraKsiazka i NowaKsiazka zawierają bieżące
elementy łączonych plików.}
170
5. Bazy danych
{Dane:
Plik - podstawowy zbiór książek,
Nabytki - plik z nowo otrzymanymi książkami;
Wynik:
NowyPlik - plik zawierający wszystkie książki.}
VAR StaraKsiazka,NowaKsiazka:Książka;
BEGIN
READ(Plik,StaraKsiazka);
READ(Nabytki.NowaKsiazka); i
{porównanie i dołączenie elementu wcześniejszego} i
WHILE (StaraKsiazka.Autor
IF (StaraKsiazka.Autor+StaraKsiazka.Tytuł)<
(NowaKsiazka.Autor+NowaKsiazka.Tytuł) THEN BEGIN
WRITE(NowyPlik,StaraKsiazka);
READ (Plik,StaraKsiazka)
END {THEN}
ELSE BEGIN
WRITE (NowyPlik,NowaKsiazka);
READ (Nabytki,NowaKsiazka)
END; {IF, WHILE}
{kopiowanie wartownika}
WRITE(NowyPlik,StaraKsiazka)
END; {Lacz}
Uwaga: Tekst procedury Lacz jest umieszczony na dyskietce w programie Polacz, który
znajduje się w pliku POLACZ.PAS w kartotece R0ZDZ5.
Przykład 5.6. Problem z przykładu 5.4 można rozszerzyć biorąc pod uwagę, że
nasz księgozbiór może się nie tylko powiększać. Możemy chcieć podarować lub
pożyczyć komuś niektóre z naszych książek (np. bibliotece szkolnej), albo sko-
rygować informację o tym, czy książka jest na naszej półce. Z kolei ktoś może
zwrócić nam pożyczoną książkę. Informacje o takich zmianach w elementach
pliku można przechowywać w rekordzie z wariantami, w opisie którego uw-
zględnimy możliwość wykonywania jednej z następujących zmian w rekordach
pliku (przez klucz rozumiemy nadal autora i tytuł jego książki):
- usunięcie elementu(Us): w tym przypadku wystarczy podać klucz usuwa-
nego elementu;
- uaktualnienie (Akt): oprócz klucza należy podać nową wartość pola, którego
zawartość chcemy uaktualnić (w naszym przykładzie będzie to pole Jest);
i
5.3. Aktualizacja bazy danych
171
- wstawienie elementu (Wst): oprócz informacji zawartej w kluczu należy
podać wartości pozostałych pól (w naszym przypadku będzie to ponownie
pole Jest);
W przykładzie 5.4 opisaliśmy jak postępować, jeśli wszystkie zmiany, jakie
mamy wykonać w pliku, polegają tylko na wstawianiu nowych elementów. Teraz
napiszemy procedurę, która będzie wykonywać ciąg dowolnych, wymienionych
wyżej zmian.
Zdefiniujmy typ wyliczeniowy Operacja. Zmienne tego typu będą mogły
przyjmować jedną z trzech wartości: Us (usuń), Akt (aktualizuj), Wst (wstaw).
TYPE Operacja=(Us,Akt,Wst)
Opiszemy teraz strukturę zmiennej zawierającej informacje o książce (czyli
pola Autor, Tytuł) oraz określenie wprowadzanej zmiany Zmień. Chcemy aby
zmienne, w których wartością pola Zmień jest Akt lub Wst miały w swojej struk-
turze ponadto pole Jest (informację o tym czy książka jest aktualnie u nas).
Jeśli zaś wartością pola Zmień będzie Us, to pole Jest nie powinno wystąpić
w strukturze zmiennej.
Do zdefiniowania zmiennych o tak skomplikowanej strukturze użyjemy re-
kordu z wariantami. Wartość pola Zmień określa aktualny wariant struktury
zmiennej. W opisie odpowiedniego rekordu, możliwe warianty zmiennej są opi-
sane w części rozpoczynającej się słowem kluczowym CASE i występującej na
końcu w wykazie pól rekordu. Pola, które występują w danym wariancie umie-
szczamy w nawiasach okrągłych. Same nawiasy z pustą zawartością, tzn. (),
oznaczają brak dodatkowych pól.
Korzystając z rekordu z wariantami pojedynczą zmianę w elemencie pliku
można scharakteryzować informacją o następującej strukturze:
TYPE Zmiana=RECORD
Autor:Napis30;
Tytuł:Napis50;
CASE Zmień :Operacja OF
{przy usuwaniu elementu nie jest
potrzebna żadna informacja o in-
nych polach}
Us :();
{wstawianie i uaktualnianie wyma-
gają informacji o innych polach}
(Jest:B00LEAN)
END;
Akt,Wst:
{Zmiana}
Załóżmy, że plik StaryKatalog został zdefiniowany podobnie jak plik Katalog
w przykładzie 5.4, jego elementy są uporządkowane i nie powtarzają się. Nato-
172
5. Bazy danych
miast nanoszone zmiany są zapisane w pliku Poprawki typu:
Zmiany=FILE OF Zmiana
Przyjmijmy ponadto, że elementy w pliku Poprawki są także uporządkowane
ze względu na niemałejące wartości klucza. Natomiast w ciągu zmian (poprawek)
z tą samą wartością klucza nie naruszamy porządku, w jakim te zmiany zostały
zapisane w pliku Poprawki. Nie każdy ciąg zmian jest poprawny. Nie możemy
na przykład wykonać dwóch zmian polegających na usunięciu elementu o tej
samej wartości klucza, a dla ciągu zmian, mających identyczną wartość klucza
i opisujących operacje
Wst, Akt, Us, Us, Akt
drugie Us i drugie Akt powinny spowodować pojawienie się komunikatu o błędzie.
Algorytm 5.4. Nanoszenie poprawek w pliku. Zmiany w pliku StaryKatalog,
które są zapisane w pliku Poprawki, można wykonać w następujący sposób:
1. Przeczytaj element Sk z pliku StaryKatalog.
2. Przeczytaj element Zm z pliku Poprawki.
3. WHILE (Sk.AutorOWartownik) OR (Zm.AutorOWartownik) DO
przetwarzaj rekord z pliku StaryKatalog lub Poprawki.
4. Dopisz wartownika do nowo utworzonego pliku NowyKatalog.
Jeśli warunek występujący w pętli WHILE jest spełniony, to istnieje co najmniej
jeden element w pliku StaryKatalog lub w pliku Poprawki opatrzony kluczem
(Klucz=Autor+Tytul), którego wartość spełnia warunek Klucz
o tej samej wartości klucza. W pierwszym z plików może być co najwyżej jeden
taki element, a w drugim - wiele.
Poniżej przedstawiamy opis procedury PrzetwPliki, która tworzy nowy kata-
log na podstawie starego katalogu i pliku zawierającego zmiany, do uwzględnienia
w katalogu. Pierwsza instrukcja IF w procedurze określa wartość klucza i przy-
pisuje ją zmiennej BKlucz (bieżący klucz). W tej samej instrukcji zmiennej
PSk (pomocnicza zmienna - wartość elementu z pliku StaryKatalog) zostaje
przypisana wartość początkowa. Jeśli wartość bieżącego klucza pochodzi z pliku
StaryKatalog, to jest przetwarzany jedyny element z tego pliku o tej wartości
klucza. W przeciwnym przypadku nie wykonujemy żadnych działań na elemen-
tach pliku StaryKatalog. Następująca po instrukcji IF instrukcja WHILE ana-
lizuje wszystkie zmiany (Zm) mające tę ustaloną wartość klucza. W ostatniej
instrukcji w treści procedury zmodyfikowany element jest dopisywany do uaktu-
alnionego pliku NowyKatalog.
5.3. Aktualizacja bazy danych
173
PROCEDURĘ PrzetwPliki(VAR StaryKatalog,NowyKatalog:Księgozbiór;
VAR Poprawki:Zmiany);
{Zgodnie ze zmianami zapisanymi w pliku Poprawki, procedura
modyfikuje plik StaryKatalog generując uaktualniony plik
NowyKatalog.}
{Dane:
StaryKatalog
Poprawki
katalog książek;
informacje o zmianach, które należy wy-
konać w pliku StaryKatalog;
Wynik:
NowyKatalog
VAR BKlucz,
SkKlucz,
uaktualniony katalog książek.}
{bieżący klucz}
{klucz elementu odczytanego z
pliku StaryKatalog}
ZmKlucz:STRING[50];{klucz elementu z pliku Poprawki}
{bieżąca i pomocnicza informacja
o książce z katalogu}
{pojedynczy element z pliku Poprawki}
Sk.PSk :Książka;
Zm :Zmiana;
BEGIN
{Skojarzenie plików: StaryKatalog, Poprawki, NowyKatalog
z plikami fizycznymi powinno zostać wykonane w programie
wykorzystującym te procedurę.}
RESET(StaryKatalog); RESET(Poprawki);
REWRITE(NowyKatalog);
READ(StaryKatalog,Sk);
READ(Poprawki,Zm);
SkKlucz:=Sk.Autor+Sk.Tytuł;
ZmKlucz:=Zm.Autor+Zm.Tytuł;
WHILE (SkKlucz
BKlucz:=SkKlucz;
PSk:=Sk;
READ(StaryKatalog,Sk);
SkKlucz:=Sk.Autor+Sk.Tytuł
END {THEN}
ELSE BEGIN {SkKlucz>ZmKlucz}
BKlucz:=ZmKlucz;
PSk.Autor:=Wartownik
END; {nadano wartość zmiennej BKlucz}
174
5. Bazy danych
WHILE ZmKlucz=BKlucz DO BEGIN
IF PSk.Autor
Akt:PSk.Jest:=Zm.Jest;
Us :PSk.Autor:=Wartownik;
Wst:WRITELN('Niepoprawna zmiana')
END {CASE}
ELSE IF Zm.Zmien=Wst THEN BEGIN
PSk.Jest:=Zm.Jest;
PSk.Autor:=Zm.Autor;
PSk.Tytuł:=Zm.Tytuł
END; {THEN>
READ(Poprawki, Zm);
ZmKlucz:=Zm.Autor+Zm.Tytuł
END; {WHILE}
{Wartość klucza kolejnego elementu z pliku Poprawki
i pliku StaryKatalog jest większa niz BKlucz.}
IF PSk.Autor
WRITE(NowyKatalog.Sk) {dopisanie wartownika}
END; {PrzetwPliki}
Uwaga: Tekst procedury PrzetwPliki znajduje się na dyskietce w pliku PRZETWPL.PAS
umieszczonym w kartotece RDZDZ5.
W przykładzie 5.2 opisaliśmy program, który tworzy plik fizyczny w pamięci
zewnętrznej komputera. Plik ten można potem wykorzystać w innym programie
modyfikującym jego zawartość (np. za pomocą procedury PrzetwPliki). Zmo-
dyfikowany plik będzie także plikiem fizycznym i można go również przetwarzać.
5.4. Systemy baz danych
Nasze dotychczasowe doświadczenia z posługiwania się bazami danych uświada-
miają nam dwa fakty:
- nawet w prostym zadaniu, polegającym na założeniu i aktualizowaniu ka-
talogu domowej biblioteki, szybko daje o sobie znać potrzeba korzystania
z więcej niż jednego pliku;
w odniesieniu do różnych plików mają zastosowanie różnorodne działania i
modyfikujące, które z uwagi na sposób przechowywania plików (w pamięci
zewnętrznej) mogą być wykonywane nawet przez oddzielne programy (por.
zad. 5.3, 5.4, 5.5).
5.4. Systemy baz danych
175
W praktyce ewidencja danych i korzystanie z bardziej złożonych zbiorów in-
formacji (np. dotyczących wielooddziałowej biblioteki, magazynu części i półfab-
rykatów, rozliczeń finansowych itp.) wymagają znacznej liczby plików o różnych
strukturach, w których obieg informacji i jej przetwarzanie może przybierać bar-
dzo złożone formy. Mówimy w takich przypadkach o istnieniu systemów baz
danych.
Systemy baz danych, czyli powiązane ze sobą zbiory informacji oraz progra-
my, które je porządkują, uaktualniają i wyodrębniają z nich potrzebne informacje,
są ważnymi zastosowaniami informatyki. Problemy zarządzania informacją ist-
niały i były rozwiązywane zanim pojawiły się komputery. Jednym z przykładów
może być rezerwacja miejsc hotelowych umożliwiająca uzyskanie danych o ak-
tualnie zajętych miejscach według dni, wielkości pokoi i standardu wyposażenia.
Udziałem komputerów jest natomiast istotna zmiana w technologii przetwarzania
informacji.
Do typowych działań na bazach danych należą:
1. Przetwarzanie bazy z wykorzystaniem następujących operacji wykonywa-
nych na jej elementach:
- wyszukiwanie (na przykład, by uzyskać informacje o wolnych miejscach
w samolotach lub pociągach),
- wstawianie,
- usuwanie,
- uaktualnianie (tj. uzupełnianie stanu komputerowej kartoteki, pól, po-
szczególnych rekordów).
2. Działania ściśle użytkowe, jak:
- wyszukiwanie elementów bazy na podstawie ustalonych kryteriów (np.
sporządzenie wykazu tych użytkowników dróg, którzy w ustalonym
okresie popełnili więcej niż jedno wykroczenie drogowe),
- okresowe przetwarzanie bazy danych (np. okresowe dopisywanie odse-
tek do kont posiadaczy rachunków oszczędnościowo-rozliczeniowych),
- sporządzanie zestawień, raportów, wyciągów, statystyk w różnych for-
mach: tabel, wykresów, diagramów.
Jeśli system bazy danych dotyczyłby nie naszego księgozbioru, lecz na przyk-
ład biblioteki szkolnej, to wówczas rozbudowalibyśmy typ Książka o dodatkowe
pola opisujące m.in. sygnaturę, rok, miejsce wydania książki itd.
Jeszcze bardziej rozbudowany byłby zbiór informacji o książkach we wszyst-
kich bibliotekach naszego miasta. Wyodrębnilibyśmy wówczas informację o tym,
w której bibliotece jest dana książka. W bazie danych moglibyśmy umieścić od-
dzielne pliki opisujące osobno zawartość każdej biblioteki lub informacje o wszy-
stkich książkach byłyby pamiętane w jednym pliku. W tym drugim przypadku
176
5. Bazy danych
należałoby rozszerzyć informację o każdej książce o identyfikator biblioteki. Na-
tomiast osobno przechowywalibyśmy nazwy (i inne dane o bibliotece) oraz iden-
tyfikator. Dla przykładu odpowiednie typy danych mogłyby mieć postać:
TYPE Napis30
Napis50
Książka
I
=STRING[30];
=STRING[50];
=REC0RD
Autor:Napis30;
Tytuł:Napis50;
Jest:B00LEAN;
Iden:INTEGER {identyfikator}
END; {Książka}
Biblioteka=RECORD
Idend :INTEGER; {identyfikator}
Nazwa,Adres:Napis50
END; {Biblioteka}
Czy zbudowany przez nas system bazy danych o książkach zmieniłby się
bardzo, gdybyśmy chcieli w podobny sposób przechowywać oraz uzyskiwać in-
formacje o naszej kolekcji znaczków? Oczywiście zmianie uległaby podstawowa
struktura danych opisująca pojedyncze elementy pliku. Na przykład, zamiast na-
zwiska autora i tytułu książki musielibyśmy przeznaczyć pola na zapisanie m.in,
następujących informacji o znaczku: państwo i rok wydania, nominał, nazwa serii
lub numer katalogowy. Same algorytmy przetwarzania plików pozostałyby bez
zmian.
Podkreślmy z naciskiem, że komputery mogą nam pomóc w efektywnej i rze-
telnej obróbce informacji, ale same nie naprawią błędów i nie poprawią nie-
dokładnych informacji. Toteż decydując się na komputeryzację jakiejś bazy in-
formacji należy z dużą pieczołowitością zająć się jej tworzeniem w komputerze.
Komputery w żadnym wypadku nie są lekarstwem na bałagan.
Rozważmy jeszcze jeden przykład wzięty z naszego otoczenia - tradycyjną
książkę telefoniczną. Najczęściej wykonywaną operacją jest wyszukiwanie nu-
meru telefonu określonego abonenta. Inne operacje na tej bazie danych (w pos-
taci książki telefonicznej) powodujące zmianę jej zawartości, jak na przykład:
- usunięcie abonenta z książki telefonicznej,
- zmiana numeru telefonu,
- dopisanie nowego abonenta,
mogą być wykonywane przez niewielką grupę użytkowników upoważnionych do
nadzorowania takiej bazy. Zauważmy, że uwzględnienie zmian w elektronicznej
książce telefonicznej nie wymaga drukowania kolejnego wydania tej książki. Ak-
tualizację skomputeryzowanej książki telefonicznej ułatwia to, że wszyscy użyt-
5.4. Systemy baz danych
177
kownicy korzystają z jednego jej "egzemplarza", a nie każdy z innego, wydruko-
wanego oddzielnie. Co więcej, wszyscy mają dostęp do zmodyfikowanej wersji
książki natychmiast po naniesieniu zmian, bez konieczności kupowania jej no-
wego wydania. Ta wersja książki telefonicznej ma więc wiele zalet w porównaniu
z książką wydrukowaną. Takie możliwości mają na przykład abonenci telefoniczni
we Francji dzięki systemowi Minitel.
Ochrona baz danych
Niebagatelnym problemem, z którym poradzić sobie muszą twórcy i użytkow-
nicy baz danych, jest ochrona zawartych w bazach informacji. W praktyce
ochrona bazy danych może dotyczyć tylko niektórych wybranych jej fragmentów
lub operacji.
System, który zarządza bazą danych, powinien przynajmniej identyfikować
użytkownika, który chce mieć do niej dostęp i określać, jakie operacje na bazie
danych może on wykonywać. Jako przykład wprowadzimy pewne zabezpieczenie,
które nie pozwoli niepowołanym osobom dokonywać jakichkolwiek zmian w pliku
Katalog bez naszej zgody.
Ponieważ sami chcemy wprowadzać zmiany w katalogu, a innym osobom
pozwalamy tylko oglądać nasz katalog, opiszemy funkcję, która będzie spra-
wować pieczę nad dostępem do danych. Następująca funkcja przyjmuje wartość
TRUE tylko wtedy, gdy hasło podane przez użytkownika zgadza się z hasłem za-
strzeżonym przez nas.
Przykład 5.7. Sprawdzanie hasła.
FUNCTION Identyfikacja:BOOLEAN;
{Funkcja przyjmuje wartość TRUE tylko wtedy, gdy użytkownik
zapytany o hasło poda to, które zostało ukryte w stałej
MojeHaslo.}
{MojeHaslo jest stalą globalna, której wartość określamy
w czesci definiującej stale w programie.}
VAR Hasło:STRING;
BEGIN
{sprawdzanie dostępu do bazy danych}
WRITELNCPodaj hasło: ');
READLN(Hasło);
Identyf ikacj a:=Haslo=Moj eHaslo
END; {Identyfikacja}
Uwaga: Tekst funkcji Identyfikacja znajduje się na dyskietce w pliku IDENTYF.PAS
umieszczonym w kartotece R0ZDZ5.
12 Elementy informatyki
178
5. Bazy danych
Funkcja, którą zdefiniowaliśmy identyfikuje tylko użytkownika. Możemy użyć
tej funkcji (lub podobnej) w programie, gdy ma być wykonana operacja odczyta-
nia lub zapisania (lub np. tylko operacja zapisania). Wtedy, przed wykonaniem
operacji należy sprawdzić, czy użytkownik zna hasło, które upoważnia go do jej
wykonania.
Schemat kontroli i ochrony danych może mieć następującą postać:
- W systemie są zakodowane identyfikatory oraz hasła użytkowników i ża-
den użytkownik bez ważnego identyfikatora i hasła nie ma dostępu do bazy |
danych.
- Dla użytkownika mającego dostęp do bazy danych jest określony zakres!
dostępu, czyli dostępne pliki (ich fragmenty lub pola elementów) i dozwo-
lone na nich operacje.
Typowym przykładem ograniczenia dostępu do bazy jest umożliwienie czyta-
nia zawartości pliku z równoczesnym zakazem jego modyfikowania.
Ogólnie rozróżnia się trzy stopnie swobody:
- zezwolenie na odczytywanie, zapisywanie i zmianę zawartości,
- zezwolenie na odczytywanie i zapisywanie (nowych rekordów),
- zezwolenie tylko na odczytywanie.
Potrzeba jest matką ... języka [programowania]
Nawet po tym bardzo pobieżnym przeglądzie własności systemów baz danych oraz
korzyści z nich płynących można dojść do wniosku, że byłoby dobrze dysponować
językiem (lub ogólniej systemem programowania) przeznaczonym do budowania
i obsługi baz danych w całej ich różnorodności.
Język taki powinien umożliwiać:
- definiowanie bazy danych na podstawie nazw i typów pól w rekordzie re- j
prezentującym element pliku tworzącego bazę danych,
- usuwanie wskazanego elementu pliku,
- modyfikowanie wskazanego elementu pliku,
- wyszukiwanie elementów według podanego klucza.
Operacje te są typowe dla większości baz danych, takich jak nasz księgozbió|
elektroniczna książka telefoniczna, system obsługi kont w banku.
Odpowiednie systemy i języki baz danych istnieją. Są to na przykład: system!
dBASE i Clipper (na komputerach osobistych) oraz system Oracle i Progress n|
dużych komputerach.
Systemy baz danych umożliwiają użytkownikowi, który nie jest biegły w pro
gramowaniu, nie tylko korzystanie z obcych baz danych, ale również budowanij
własnych baz.
5.5. Wprowadzenie do systemu dBASE
179
5.5. Wprowadzenie do systemu dBASE
5.5.1. Wstęp
Określiliśmy już pojęcie pliku i omówiliśmy operacje na plikach w języku Pascal.
Zrobiliśmy to na przykładzie prostej bazy danych reprezentującej katalog ksią-
żek. Umiemy między innymi dopisywać rekordy do bazy, aktualizować bazę lub
usuwać z niej rekordy. Teraz podamy realizację tych samych operacji zastosowa-
nych do przykładowej bazy danych, ale w systemie przystosowanym specjalnie do
działań na bazach danych. Jednym z takich systemów ułatwiających tworzenie
baz danych i ich obsługę jest system dBASE.
Naszym celem jest zaprezentowanie jedynie pierwszych kroków w systemie
dBASE. Korzystać przy tym będziemy z tego systemu w wersji dBASE III Plus,
posługując się nim w trybie konwersacyjnym. Podamy tylko te informacje o sy-
stemie, które są niezbędnie potrzebne do rozwiązania występujących w tym roz-
dziale zagadnień. Z tego powodu przytoczone postacie poleceń systemu dBASE
nie opisują ich wszystkich możliwych wariantów.
Pracę z systemem dBASE rozpoczniemy w tzw. trybie bezpośredniej konwer-
sacji. Gotowość systemu do pracy (czyli do przyjmowania poleceń) w tym trybie
jest zgłaszana znakiem zaproszenia, którym w systemie dBASE jest standardowo
znak . (kropka).
Polecenie systemu dBASE piszemy podając jego nazwę oraz o ile to jest wy-
magane - parametr albo listę parametrów i fraz modyfikujących jego działanie.
Poszczególne elementy polecenia należy oddzielać co najmniej jednym odstępem.
Najczęściej występującymi parametrami poleceń są zakres i lista pól (oddzielo-
nych przecinkami). Jedną z fraz modyfikujących, której znaczenie nie zależy od
polecenia, jest fraza FOR wyrażenie. Wprowadzanie polecenia kończymy naciśnię-
ciem klawisza | Enter |. Rola tego klawisza jest w tym systemie rozbudowana,
zwłaszcza przy wprowadzaniu danych. Na przykład, w trakcie wprowadzania war-
tości do pól rekordu naciśnięcie klawisza | Enter | kończy wprowadzanie informa-
cji do wyróżnionego pola (podobne znaczenie w tej sytuacji ma klawisz |> |). Z
kolei naciśnięcie | Enter | zamiast wpisania pierwszego znaku w pierwszym polu
kolejnego rekordu bazy jest sygnałem końca wprowadzania informacji do bazy.
Opiszemy teraz pokrótce sposoby korzystania z systemu dBASE na przykła-
dach zadań przedstawionych w poprzednich punktach tego rozdziału.
5.5.2. Tworzenie bazy danych
Tworzymy własną bazę danych - katalog książek znajdujących się w naszym
księgozbiorze. Przyjmiemy, podobnie jak w programach zrealizowanych w języku
Pascal, że podstawowa informacja dotycząca pojedynczej książki składa się z na-
?
180
5. Bazy danych
zwiska i imienia jej autora oraz jej tytułu (por. p. 5.1). Dodatkowo będzie podana
również informacja o tym czy wypożyczyliśmy komuś tę książkę, czy też znaj-
duje się ona na naszej półce. Informację o książce zapiszemy w postaci rekordu
złożonego z pól AUTOR i TYTUŁ typu napisowego i pola JEST typu logicznego.
Definiowanie struktury nowego pliku bazy danych4 rozpoczynamy od wyda-
nia polecenia
CREATE nazwa-pliku
Naszą bazę nazwiemy Katalog, zatem poleceniem inicjującym tworzenie no-
wego pliku bazy danych jest w tym przypadku CREATE Katalog.
System rozpocznie pracę od umieszczenia kursora w pierwszym polu. Możemy
przystąpić do definiowania struktury rekordów bazy podając nazwy, typy i roz-
miary poszczególnych pól.
Typ pola, czyli typ wartości umieszczanych w tym polu, określamy podając
jedną z liter:
C - pole znakowe, tj. przeznaczone na napisy;
N - pole liczbowe, czyli zawierające liczby;
L - pole logiczne, przechowujące wartości logiczne prawdę lub fałsz;
D - pole daty;
M - pole notatnikowe zawierające uwagi.
W naszych przykładach nie korzystamy z dwóch ostatnich typów pól.
Rozmiar pola rekordu w systemie dBASE jest mierzony liczbą znaków, które
mogą być umieszczone w tym polu. Rozmiar pola znakowego jest całkowitą liczbą
znaków, które mogą być w nim zapisane i wynosi co najwyżej 254. Pole liczbowe
może mieć rozmiar co najwyżej 19 znaków, przy czym znakami w tym przypadku
są cyfry, znak liczby (+ lub ) oraz kropka dziesiętna. Liczba może mieć co
najwyżej 15 cyfr po kropce. Jeśli nie podamy liczby cyfr po kropce lub jest ona
równa 0, to w takim polu liczbowym można umieszczać tylko liczby całkowite.
Pole logiczne ma rozmiar jednego znaku przeznaczonego na literę T (od TRUE -
prawda) lub F (od FALSE - fałsz).
Wprowadzimy teraz zgodne z przykładem 5.1 informacje dotyczące struktury
rekordów w definiowanym przez nas pliku danych. Rekord składa się z trzech pól:
AUTOR typu C i rozmiaru 30, TYTUŁ typu C i rozmiaru 50 oraz JEST typu L.
Definiowanie struktury rekordu w pliku bazy danych kończymy naciśnięciem
klawisza | Enter [ zamiast wprowadzenia pierwszego znaku nazwy kolejnego pola.
4System dBASE korzysta z wielu rodzajów plików, które są rozróżniane za pomocą rozszerzeń
ich nazw. W tym punkcie wykorzystujemy jedynie pliki, które mają standardowe rozszerzenie
DBF. Nazywamy je tutaj plikami bazy danych lub plikami danych. Ich nazwy podajemy bez
rozszerzenia.
5.5. Wprowadzenie do systemu dBASE
181
System wymaga potwierdzenia tej decyzji - wyświetlając u dołu ekranu komu-
nikat: Press Enter to confirm. Any other key to resume. Naciśnięcie kla-
wisza |Enter| oznacza potwierdzenie, a każdego innego klawisza - powoduje
powrót do dalszego definiowania struktury rekordu.
Po zakończeniu definiowania struktury rekordu pojawia się pytanie:
Input data records now? (Y/N)
Odpowiadamy na nie twierdząco (tj. Y), jeśli chcemy zacząć wprowadzać kon-
kretne dane do tworzonej bazy, czyli naśladować czynności wykonywane przez
program z przykładu 5.3. Wtedy pojawia się wzorzec pól rekordu z zaznaczonym
obszarem na konkretne dane.
Możemy rozpocząć wprowadzanie informacji o kolejnych książkach z naszej
biblioteki wypełniając pola zgodnie z wyświetlanym wzorcem. Wprowadzanie
wartości do poszczególnych pól kończymy naciśnięciem klawisza | Enter |. Podob-
nie kończymy tworzenie pliku bazy w momencie, gdy pojawia się nowy rekord do
wypełnienia. Dane możemy podawać w porządku alfabetycznym nazwisk i imion
autorów oraz tytułów książek.
Zauważmy już teraz, że w systemie baz danych takim jak dBASE, w przeci-
wieństwie do języka Pascal, nie musimy definiować specjalnych procedur służą-
cych do tworzenia struktury rekordów bazy, wypełniania ich konkretnymi war-
tościami, a także wykonywania na nich operacji. Za pomocą polecenia CREATE
definiujemy strukturę rekordów pliku bazy danych oraz możemy wprowadzać do
ich pól konkretne wartości.
Plik utworzony za pomocą polecenia CREATE staje się aktywny. Wszystkie
omawiane w tym punkcie polecenia dotyczą aktywnego pliku danych.
Aby uaktywnić plik danych o nazwie nazwa-pliku, wydajemy polecenie
USE nazwa-pliku
zamykające jednocześnie plik danych, który był dotąd aktywny. Wydanie pole-
cenia USE bez parametru zamyka otwarty (aktywny) plik danych.
W aktywnym pliku danych rekord aktualnie dostępny dla poleceń nazywa
się rekordem bieżącym. Można jednak określić w poleceniu, że dotyczy ono
innego rekordu niż rekord bieżący. Zmiana bieżącego rekordu może być wynikiem
wykonania polecenia lub efektem ubocznym innego polecenia. Na przykład:
- po uaktywnieniu (otwarciu) pliku bazy danych poleceniem USE lub CREATE
rekordem bieżącym jest pierwszy rekord,
- po wykonaniu polecenia dotyczącego wszystkich rekordów (np. LIST) re-
kordem bieżącym jest pusty rekord po ostatnim rekordzie bazy,
- po wykonaniu polecenia dotyczącego grupy rekordów bieżącym jest rekord,
dla którego polecenie zostało wykonane ostatnio.
182
5.5.3. Wyświetlanie zawartości bazy danych
Zawartość pliku bazy danych utworzonego przez system dBASE możemy wyświet-
lić, aby na przykład sprawdzić czy nie popełniliśmy błędów przy wprowadzaniu
danych (podobne jest działanie procedury DrukEcho z przykładu 5.3). W tym
celu wystarczy skorzystać z polecenia DISPLAY lub LIST.
Jeśli nie zrobiliśmy tego dotychczas, to musimy najpierw uaktywnić plik da-
nych, którym w naszym przypadku jest Katalog. Wydajemy więc polecenie
USE Katalog. Struktura rekordu w aktywnym pliku danych jest wyświetlana po
wydaniu polecenia
lub
DISPLAY STRUCTURE
LIST STRUCTURE
Z kolei zawartości pól rekordów w pliku danych wyświetlamy używając pole-
cenia
DISPLAY zakres
gdzie zakres może mieć jedną z następujących postaci:
ALL - oznacza wszystkie rekordy pliku danych,
NEXT n - oznacza n kolejnych rekordów począwszy od bieżącego,
RECORD n - oznacza rekord o numerze n,
REST - oznacza wszystkie rekordy począwszy od bieżącego aż do końca.
W opisanych i używanych dalej poleceniach DISPLAY, DELETE, RECALL i EDIT
brak zakresu wśród parametrów oznacza przyjęcie zakresu domyślnego, którym
w przypadku tych poleceń jest bieżący rekord, a w przypadku polecenia LIST -
cały aktywny plik bazy danych.
Możemy sprawdzić (na przykład na naszym pliku Katalog), że wydanie po-
lecenia DISPLAY ALL powoduje wyświetlanie zawartości całego pliku bazy da-
nych partiami po 15 rekordów (wyświetlanie jest kontynuowane po naciśnięciu
dowolnego klawisza). Polecenie DISPLAY NEXT 2 powoduje wyświetlenie dwóch
rekordów, tj. bieżącego i następującego po nim, a po wydaniu polecenia
DISPLAY RECORD 2
jest wyświetlana zawartość tylko drugiego rekordu z pliku danych. 1
Domyślny zakres polecenia może zostać zmieniony na ALL, gdy jednym z pa-j
rametrów polecenia jest fraza FOR wyrażenie. Fraza ta umożliwia wybieranie do \
przetwarzania tylko tych rekordów z danego zakresu, które spełniają warunek j
określony przez wyrażenie i można ją umieścić na końcu poleceń LIST i DISPLAY,
jak również w poleceniach DELETE, RECALL, EDIT, które omawiamy w dalszej
5.5. Wprowadzenie do systemu dBASE
183
części. W szczególności polecenie DISPLAY FOR wyrażenie powoduje wyświetlenie
wszystkich tych rekordów z całej bazy danych, które spełniają warunek określony
przez wyrażenie. Jeśli na przykład chcemy wyświetlić dane o wszystkich książkach
z naszego księgozbioru Katalog napisanych przez Sienkiewicza, to wydajemy po-
lecenia
USE Katalog
DISPLAY FOR AUT0R='Sienkiewicz'
Działanie poleceń LIST i DISPLAY jest bardzo podobne. Różnica polega na
tym, że
- jeśli nie jest podany zakres polecenia LIST, to zakresem domyślnym są
wszystkie rekordy aktywnego pliku bazy danych, a w przypadku polece-
nia DISPLAY - bieżący rekord;
- polecenie LIST powoduje ciągłe wyświetlanie rekordów bazy, a polecenie
DISPLAY - wyświetlanie rekordów partiami.
5.5.4. Aktualizowanie bazy danych
Przejdźmy teraz do uaktualniania bazy danych. Omówimy wybrane polecenia
związane z włączaniem i usuwaniem danych, zmianą zawartości rekordów bazy
i ich porządkowaniem (sortowaniem).
Dołączanie rekordów
Przypuśćmy, że aktywnym plikiem danych jest plik Katalog i chcemy dołączyć
do niego informacje o nowo nabytych książkach. Uzupełnianie bazy o nowe re-
kordy można zorganizować na dwa sposoby:
1. Dołączać do niej natychmiast każdy nowy rekord, gdy tylko się pojawi pełna
informacja o nim.
2. Gromadzić informacje o nowych rekordach w osobnym pliku (ale o takiej
samej strukturze rekordów), a następnie okresowo uaktualniać główną bazę
danych informacjami z tego pomocniczego pliku.
Omówimy oba sposoby w odniesieniu do naszego pliku Katalog. Plik danych,
w którym będziemy gromadzić dane o nowych książkach, nazwijmy Nabytki. Plik
ten można utworzyć w podobny sposób jak plik Katalog za pomocą polecenia
CREATE. Istnieje jednak prostszy sposób polegający na utworzeniu pliku Nabytki
i jednocześnie skopiowaniu do niego struktury rekordów z pliku Katalog. W tym
celu należy wydać polecenie
COPY STRUCTURE TO Nabytki
gdy aktywny jest plik Katalog.
184
5. Bazy danych
Dołączanie nowych książek do jednego z tych plików odbywa się podobnie.
Najpierw ustalamy poleceniem USE, który plik ma być aktywny, a następnie wy-
dajemy polecenie
APPEND
bez parametrów, które powoduje, że system będzie oczekiwał na wprowadzanie
nowych danych z klawiatury. Nowe dane są dołączane do aktywnego pliku bazy
danych.
Jeśli zdecydowaliśmy się okresowo uaktualniać plik Katalog, to sposobem
opisanym powyżej gromadzimy dane o nowych książkach w pliku Nabytki. Wy-
dajemy polecenia:
USE Nabytki
APPEND
a następnie wprowadzamy dane o książkach, które otrzymaliśmy. Wprowadza-
nie kończymy naciśnięciem | Enter | zamiast wpisania informacji do kolejnego
rekordu. Zawartość pliku Nabytki dołączamy co jakiś czas do pliku Katalog wy-
dając polecenia
USE Katalog
APPEND FROM Nabytki
Jeśli zawartość pliku bazy danych jest uzupełniana poleceniem APPEND, to ko-
lejne rekordy są dopisywane do końca pliku. Zatem w naszym przypadku, jeśli
plik danych Katalog był uporządkowany, np. względem nazwisk (i imion) au-
torów oraz tytułów książek, to po dopisaniu do niego nowych rekordów porządek
ten może zostać zaburzony. Pliki baz danych można jednak porządkować stosując
polecenie SORT, które ustawia rekordy w porządku wyznaczonym przez zawartoś-
ci wyróżnionych pól. Polecenie to ma postać
SORT TO plik ON lista-pól ASCENDING
lub
SORT TO plik ON lista-pól DESCENDING
gdzie plik jest nazwą pliku danych, do którego zostaną przepisane rekordy ak-
tywnego pliku bazy w niemałej ącej (w pierwszym przypadku) lub nierosnącej
(w drugim przypadku) kolejności wartości klucza w polach rekordów o nazwach
wymienionych w wykazie lista-pól5.
Podobny efekt, jak w pierwszym przypadku otrzymujemy wydając polecenie
SORT bez określenia porządku (zobacz ciąg poleceń na następnej stronie.)
5Innym sposobem porządkowania rekordów w bazie danych, o którym nie piszemy tutaj, jest
indeksowanie.
5.5. Wprowadzenie do systemu dBASE
185
Jeżeli mamy uporządkować rekordy według zawartości kilku pól, tak jak
w pliku Katalog (według nazwiska i imienia autora oraz tytułu książki), to w wy-
kazie pól umieszczamy nazwy tych pól w kolejności ich ważności dla przyjętego
porządku.
Zatem ciąg poleceń porządkujących plik Katalog będzie miał postać:
USE Katalog
SORT ON AUTOR,TYTUŁ TO Chwilowy
USE Chwilowy
COPY TO Katalog
Po wydaniu ostatniego polecenia u dołu ekranu ukazuje się informacja, że
baza Katalog istnieje, i pytanie czy można ją zniszczyć zapisaniem w niej nowej
postaci katalogu. Decydujemy, że tak (pisząc Y). Zawartość posortowanej bazy
możemy sprawdzić wydając polecenia USE Katalog i DISPLAY ALL. Plik Katalog
zawiera te same rekordy co uprzednio, ale teraz są one uporządkowane alfabetycz-
nie względem nazwisk (i imion) autorów oraz tytułów książek. Podobny wynik
otrzymaliśmy w p. 5.3 stosując procedurę Lacz (por. przykład 5.5), która scala
dwa uporządkowane pliki w jeden plik uporządkowany.
Kolejnym poleceniem w systemie dBASE, które dołącza rekordy do bazy, jest
INSERT. Wywołanie tego polecenia bez frazy BEFORE powoduje wstawienie dodat-
kowego rekordu po bieżącym rekordzie, a w postaci
INSERT BEFORE
- przed bieżącym rekordem. Samo wpisywanie wartości pól w kolejnych rekordach
przebiega podobnie jak w przypadku poleceń CREATE i APPEND. Rekord wstawiony
staje się rekordem bieżącym.
I
I
Usuwanie rekordów
Omówimy teraz działanie poleceń, które pozwalają usuwać rekordy z pliku bazy
danych. Ponieważ pliki bazy danych są zwykle traktowane jako bardzo istotne
zbiory danych i źródła uporządkowanych oraz dobrze zorganizowanych informacji,
to operacje zmieniające ich zawartość są obwarowane wieloma ograniczeniami i ich
wykonanie wymaga pewnych przygotowań. Chodzi zwłaszcza o zabezpieczenie
bazy przed przypadkowym usunięciem rekordu. Z tego powodu (jak i z powodu
dużej czasochłonności przebudowywania bazy danych) operacja usuwania składa
się z dwóch etapów: najpierw oznaczamy rekordy, które chcemy usunąć i do-
piero po upewnieniu się, że zostały zaznaczone tylko właściwe rekordy, możemy
je usunąć.
Rekordy do usunięcia oznaczamy za pomocą polecenia DELETE o postaci:
DELETE zakres FOR wyrażenie
186
5. Bazy danych
Jeżeli w tym poleceniu nie jest podany ani zakres, ani warunek (fraza FOR),
to odnosi się ono do bieżącego rekordu. Przyjmijmy teraz, że dalsze polecenia
będą się odnosić do pliku Nabytki. Wydajemy więc polecenie USE Nabytki.
Jeśli chcemy usunąć np. trzy rekordy począwszy od rekordu o numerze 2, to
przyjmujemy go najpierw jako rekord bieżący (podając numer rekordu)
a następnie zaznaczamy rekordy do usunięcia poleceniem
DELETE NEXT 3
Rekordy zaznaczone do usunięcia mają gwiazdkę umieszczoną pomiędzy nu-
merem rekordu a nazwą. Można to sprawdzić wykonując polecenie DISPLAY ALL.
Po upewnieniu się, że oznaczone zostały tylko te rekordy, które chcemy usunąć,
możemy wykonać polecenie
PACK
które wykonuje właściwą operację usuwania wszystkich rekordów oznaczonych do
usunięcia za pomocą polecenia DELETE.
Wyniki użycia polecenia DELETE (czyli oznaczenie rekordów do usunięcia)
można anulować za pomocą polecenia RECALL, którego postać ogólna jest taka
sama jak polecenia DELETE (z dokładnością do nazwy polecenia).
Zmiany w bazie danych
Wartości pól w wybranych rekordach pliku danych można zmieniać posługując
się poleceniem EDIT6. Ma ono ogólną postać
EDIT zakres FIELD lista FOR wyrażenie
Jak już wiemy, jeśli brak jest parametru określającego zakres, to zmieniane
będą zawartości pól w bieżącym rekordzie. Ponadto, jeśli w poleceniu występuje
fraza FOR, to zmieniane są tylko te rekordy, dla których jest spełniony warunek
określony przez podane wyrażenie. Na przykład, jeśli chcemy zmienić wartości
pól AUTOR i TYTUŁ w dwóch pierwszych rekordach naszej bazy Katalog, to wpro-
wadzamy następujący ciąg poleceń
EDIT NEXT 2 FIELD AUTOR,TYTUŁ
a następnie odpowiednio wypełniamy (lub pozostawiamy bez zmian) pola wyś-
wietlane przez system.
Identyczną postać ma polecenie CHANGE.
Zadania
187
Pracę z systemem dBASE kończymy pisząc polecenie QUIT. Polecenie to za-
myka wszystkie otwarte pliki i po jego wykonaniu sterowanie komputerem prze-
nosi się na poziom, z którego przeszliśmy do korzystania z systemu dBASE.
Użytkownik, który nie ma wprawy w programowaniu, może za pomocą tej nie-
wielkiej liczby poznanych dotąd poleceń nie tylko uzyskiwać informacje dostępne
w istniejącej bazie danych (LIST, DISPLAY) ale także założyć własną bazę danych
(CREATE), usunąć z niej niepotrzebne już rekordy (DELETE, PACK), dołączyć nowe
informacje (APPEND) oraz modyfikować zawartość rekordów w bazie (EDIT).
Bardziej zaawansowane działania na bazach danych wymagają uprzedniego
ich zaprogramowania. ;,
Bazy danych, które założono, mogą być obsługiwane przez osoby nie znające
programowania, jeśli tylko zostały udostępnione odpowiednio zaprogramowane
systemy ich obsługi (przykładem może być obsługa kont w banku).
Naszym celem w tym rozdziale było jednak opisanie w języku Pascal realizacji
podstawowych operacji wykonywanych przy tworzeniu i korzystaniu z baz danych.
Dysponując tymi wiadomościami osoba znająca elementy programowania w języ-
ku Pascal powinna umieć samodzielnie utworzyć bazę, a korzystając z istniejącej
bazy - będzie świadoma mechanizmów rządzących przetwarzaniem baz.
Zadania
5.1. Podaj opis pojedynczego elementu bazy danych, która zawiera informacje
dotyczące:
- danych osobowych,
- wyników nauczania uczniów w wybranej szkole (por. np. program
SredniaOcen w p. 4.4.1),
- abonentów telefonicznych,
- zużycia gazu i prądu przez pojedynczych użytkowników.
Jaką postać będzie miał opis bazy danych, reprezentującej dziennik lekcyjny
lub jego fragment?
5.2. Omawiając aktualizację i wyszukiwanie informacji w bazie danych, zakła-
damy, że jej elementy są uporządkowane według klucza. Wykorzystaj procedurę
Lacz do utworzenia uporządkowanej bazy danych.
5.3. Nanieś poprawki do istniejącej bazy danych (np. abonentowi zmieniono nu-
mer telefonu i należy to uwzględnić w bazie danych reprezentującej książkę telefo-
niczną). Napisz procedurę aktualizującą elementy bazy danych. W tym zadaniu
oraz w zadaniach 5.4 i 5.5 nie korzystaj z przykładu 5.6, lecz napisz procedurę
wykonującą ten jeden określony rodzaj zmian.
188
5. Bazy danych
5.4. Podaj szczegółowy opis algorytmu przeszukiwania księgozbioru (niekoniecz-
nie uporządkowanego). Interesują nas np. książki napisane przez wybranego au-
tora. Napisz program, który dostarczy takich informacji.
5.5. Zdecydowaliśmy się podarować część książek z naszego księgozbioru szkolnej
bibliotece. Napisz procedurę, która tylko usuwa elementy z pliku.
5.6. Utwórz, za pomocą programu TworzeniePliku z przykładu 5.2, plik za-
wierający katalog książek oraz plik zawierający nowo nabyte książki. Następnie
uzupełnij program o wykorzystanie procedury DrukEcłio z przykładu 5.3.
5.7. Korzystając z procedury Lacz (przykład 5.5), napisz program, który łączy
pliki utworzone w zadaniu 5.6, a następnie drukuje otrzymany plik za pomocą
procedury DrukEcłio.
5.8. Wykorzystując program TworzeniePliku (przykład 5.2) napisz program,
który robi to samo ale dla plików, których elementy są typu Zmiana (por. przyk-
ład 5.6).
Uwaga: Pamiętaj o tym, że wartości typu wyliczeniowego Op=(Us,Wst,Akt)
nie mogą być czytane. Można natomiast czytać pojedyncze litery (np. u, w, a)
i w zależności od wprowadzonej litery nadawać zmiennej typu Op jedną z trzech |
możliwych wartości: Us, Wst lub Akt.
5.9. Napisz procedurę DrukEcłio dla pliku, którego elementy są typu Zmiana |
(przykład 5.6). Rozwiąż zadanie 5.6 dla plików tego rodzaju.
5.10. Napisz program, który wykorzystuje procedurę PrzetwPliki zdefiniowaną j
w przykładzie 5.6.
5.11. Sprawdź, że algorytm 5.1 będzie działał poprawnie także wówczas, gdy
dopuścimy możliwość występowania kilku egzemplarzy tej samej książki w pliku j
Katalog lub w pliku Nabytki.
5.12. Napisz program, który przetworzy plik NowyKatalog (utworzony przez pro-
gram Polacz w przykładzie 5.4) na plik, który będzie można wydrukować za po-J
mocą zlecenia PRINT (systemu MS-DOS).
5.13. Zaprojektuj w systemie dBASE strukturę rekordów pliku bazy danych,j
które zawierają informacje opisane w zadaniu 5.1.
5.14. W systemie dBASE, wprowadź konkretne dane do bazy (np. zawierającej
informacje o abonentach telefonicznych), której struktura została określona w mą
wiązaniu poprzedniego zadania.
cz-
m-
1
6. OBLICZENIA W MATEMATYCE -
METODY NUMERYCZNE
6.1. Zadania numeryczne
W pracach naukowców, konstruktorów oraz technologów często jest konieczne
obliczanie wielkości określonych za pomocą skomplikowanych zależności matema-
tycznych. Doskonałymi narzędziami ułatwiającymi wykonywanie takich obliczeń
są współczesne komputery, które charakteryzują się tym, że
- liczą bardzo szybko wykonując setki tysięcy działań arytmetycznych na se-
kundę,
- umożliwiają pełną automatyzację procesu obliczeniowego.
W tym rozdziale zajmujemy się rozwiązywaniem za pomocą komputerów tak
zwanych zadań numerycznych, które polegają na obliczaniu wielkości zdefi-
niowanych za pomocą zależności matematycznych.
Przystępując do rozwiązywania zadania numerycznego, na przykład rozwią-
zywania równania kwadratowego
ax
2 + bx + c = 0
lub obliczania wartości całki oznaczonej
,6
= /
Ja
I dx
(1)
(2)
musimy najpierw opracować odpowiedni algorytm. Przyjęliśmy w poprzednich
rozdziałach (por. p. 1.2), że algorytmem jest uporządkowany ciąg podstawowych
operacji (lub instrukcji), które należy wykonać, by otrzymać rozwiązanie posta-
wionego zadania. Pamiętać przy tym należy, zwłaszcza w przypadku zadań nu-
merycznych, że komputer potrafi wykonywać tylko cztery podstawowe działania
arytmetyczne: dodawanie, odejmowanie, mnożenie i dzielenie oraz kilka operacji
logicznych (np. sprawdzanie czy liczba jest zerem lub czy jest większa od zera).
190
6. Metody numeryczne
Algorytmy będziemy zapisywać w języku Pascal. W języku tym znajdują się
niezbędne dla naszych celów funkcje standardowe, które liczą wartości ele-
mentarnych funkcji matematycznych, takich jak: pierwiastek kwadratowy SQRT,
funkcje trygonometryczne SIN i COS, logarytm LN i funkcja wykładnicza EXP. Stan-
dardowe oznacza tutaj, że nie musimy podawać komputerowi w jaki sposób (tzn.
za pomocą jakiego algorytmu) ma wyznaczać wartości tych funkcji. Kompilator
języka Pascal zawiera podprogramy, które obliczają wartości funkcji standardo-j
wych za pomocą tylko podstawowych działań arytmetycznych komputera.
To, co dotychczas powiedzieliśmy o możliwościach komputerów, oznacza, że I
opracowując algorytmy rozwiązywania zadań numerycznych możemy korzystać
tylko z bardzo ubogiego zestawu możliwych działań podstawowych, nawet jeśli
zapisujemy algorytmy w języku wysokiego rzędu. W przypadku równania kwa-1
dratowego (1) podanie algorytmu znajdowania jego pierwiastków jest dość proste,
gdyż możemy skorzystać ze znanych wzorów zawierających wykonalne w języku!
Pascal operacje arytmetyczne (algorytm ten jednak może mieć dla niektórych
współczynników a, b i c złe własności numeryczne - piszemy o tym w p. 6.4).
Gorzej jest z obliczaniem wartości całki (2), gdyż operacji całkowania nie znaj
ani komputer, ani język Pascal. Nie znamy także żadnego sposobu wyrażenia!
całki za pomocą operacji i funkcji elementarnych, z wyjątkiem tych całek, dlal
których możemy wprost wyznaczyć postać funkcji pierwotnej. W wielu jednaki
przypadkach nie potrafimy znaleźć tej funkcji - wtedy musimy skorzystać z me-l
tody przybliżonego całkowania, która prowadzi do bardzo prostego algorytmu|
obliczeń. Ale o tym powiemy dopiero pod koniec tego rozdziału.
Zadania numeryczne można zwykle rozwiązywać wieloma różnymi metodami.!
Nas interesować będą takie, które działają możliwie szybko, liczą z dużą dokła&l
nością i zajmują mało miejsca w pamięci komputera. O takich metodach mówimyj
że mają dobre własności numeryczne. W następnych punktach przeprawa
dzimy analizę wybranych zadań numerycznych i ich algorytmów właśnie
takim kątem.
Istnieją jednak zadania, dla których każda metoda daje wyniki obarczoij
dużymi błędami - są to zadania źle uwarunkowane. Przykładami takich:
dań są niektóre układy równań liniowych (zob. układ równań liniowych w p. 6.4
6.2. Błędy zaokrągleń
Dla uproszczenia naszych rozważań przyjmijmy, że każda liczba w komputerze je
zapisana w dziesiętnym układzie pozycyjnym z s cyframi. Istnieją dwa podst|
wowe sposoby pamiętania liczb w komputerze, które nazywamy reprezentacja
liczb: stałopozycyjna i zmiennopozycyjna (zob. także p. 2.1).
6.2. Błędy zaokrągleń
191
Reprezentacja stałopozycyjna
W tej reprezentacji liczby mają t cyfr po kropce dziesiętnej, s t cyfr przed
kropką oraz kropkę i znak. W szczególnym przypadku, gdy t = 0, reprezentacja
stałopozycyjna służy do pamiętania liczb całkowitych, a dokładniej liczb, które
w języku Pascal są określane mianem typu całkowitego (INTEGER). Największa
liczba w tej reprezentacji składa się z s dziewiątek i ma wartość 10s 1, a naj-
mniejsza jest do niej przeciwna. Najważniejszą własnością liczb typu całkowitego
i wartości wykonywanych na nich działań jest to, że jeśli mieszczą się między tymi
granicznymi wartościami, to są dokładne.
Reprezentacja zmiennopozycyjna
Niedogodnością reprezentacji stałopozycyjnej jest niewielki zakres wartości, jakie
mogą być przy jej pomocy zapamiętane. Znacznie większe liczby można pamiętać
w komputerze korzystając z tak zwanej znormalizowanej postaci, w której
min. są pamiętane liczby typu rzeczywistego (REAL) w języku Pascal. Re-
prezentacja ta jest także stosowana na przykład przy zapisie stałych fizycznych,
które są najczęściej albo bardzo małe, albo bardzo duże. Liczbę w postaci znor-
malizowanej zapisujemy jako
a = m 10c (3)
gdzie m jest liczbą rzeczywistą zwaną mantysą, a c jest liczbą całkowitą i nazywa
się cechą liczby a. Zakłada się, że dla o^O mantysa m spełnia nierówności:
0.1 <\m < 1.
(4)
Dla a = 0 przyjmuje się m = 0 i c = 0. Z dwóch liczb 0.0032300678 104 oraz
0.3212345678-102 druga jest w postaci znormalizowanej, gdyż jej mantysa spełnia
warunek (4).
Mantysa i cecha są pamiętane w komputerze w reprezentacji stałopozycyjnej.
Mantysa ma zero cyfr przed kropką dziesiętną, a cecha jest liczbą całkowitą.
Przyjmijmy, że dla każdej liczby w reprezentacji (3) przeznacza się t cyfr na
zapisanie mantysy, s t cyfr na zapisanie cechy, ponadto zarówno przed mantysą,
jak i cechą znajduje się miejsce na znak + lub (znak + jest zwykle opuszczany).
Zatem w pamięci komputera zamiast dokładnej wartości liczby a zostanie wpisana
jej wartość przybliżona równa
fl(a) = m 10c
(5)
gdzie m jest obciętą (a dokładniej mówiąc zaokrągloną) do t cyfr mantysą m.
Liczba fl(a) jest reprezentacją zmiennopozycyjna liczby a w komputerze. Do-
wolne przybliżenie liczby a oznaczamy dalej symbolem a.
i
192
6. Metody numeryczne
Przykład 6.1. Przyjmijmy, że na mantysę przeznaczono 5 cyfr, a na cechę-
jedną cyfrę. Oto trzy przykładowe liczby i ich komputerowe przybliżenia:
ai = 2/3 = 0.66666(6) 10, fl(oi) = 0.66667 10,
a2 = 38.762135, fl(o2) = 0.38762 102,
a3 = 0.124456 10-3, fl(a3) = 0.12446 10"3. ?
Ponieważ liczby w reprezentacji zmiennopozycyjnej są zapisywane w kompu-
terze za pomocą s cyfr, zbiór tych liczb jest skończony. Dlatego istnieje w nim
liczba o największym module K. Z drugiej strony, wśród liczb różnych od zera ist-
nieje również liczba o najmniejszym module k, k > 0. Oznacza to, że każda różna
od zera liczba zmiennopozycyjna fl(a) reprezentowalna w komputerze, spełnia
nierówności
0 < k <| fl(a) |< K.
Jeśli wynik wykonania operacji arytmetycznej na liczbach zmiennopozycyjnych
jest liczbą fł(o) taką, że
I fl(a) !> K,
to mówimy, że powstał nadmiar zmiennopozycyjny. Pojawienie się nadmiaru
jest sygnalizowane przez komputer i powoduje zatrzymanie działania programu.
Jeśli natomiast w obliczeniach pojawi się liczba fł(a) taka, że
I n(a) |< k,
to mówimy, że wystąpił niedomiar zmiennopozycyjny. W tym przypadku dzia-
łanie programu nie zostaje przerwane, a wartość fł(a) jest równa zeru. Wynika
stąd, że w zbiorze liczb zmiennopozycyjnych zero nie jest jednoznacznie repre-
zentowane.
Liczba fl(a) jest obarczona błędem powstałym przez zaokrąglenie mantysy
m do i cyfr. Określimy teraz ten błąd. Najczęściej są rozważane dwa rodzaje
błędów: bezwzględny i względny.
Błąd bezwzględny
Błąd bezwzględny ea wartości przybliżonej a jest określony wzorem
ea =| a a | .
Ponieważ m jest zaokrągleniem dokładnej wartości m do t cyfr znaczących, więc
m-fh |< 0.5-10"*.
Stąd otrzymujemy następującą nierówność dla błędu bezwzględnego przybliżenia
fl(a):
e[fl(a)] =| a - rl(a) |=| m ? 10c - rh ? 10c |< 0.5 10"* 10c.
6.2. Błędy zaokrągleń
193
Błąd względny
Błąd względny Sa wartości przybliżonej a jest określony wzorem
óa =
a a
ea
Korzystając z oszacowania błędu bezwzględnego i pierwszej nierówności w (4),
otrzymujemy następujące oszacowanie błędu względnego przybliżenia fl(a):
6[&(a)] =
a - fl(o)
0.5 10-
m-10c
10c 0.5 10-* 10c t
< ------------= 5-10 \
0.1 10c
Oznaczmy u = 5 10 *. Wielkość ta określa względną dokładność kom-
putera. Dokładność obliczeń zależy przede wszystkim od liczby t cyfr mantysy
w liczbie zmiennopozycyjnej. Mówimy wówczas, że obliczenia komputerowe są
wykonywane w arytmetyce i-cyfrowej. Z ostatniego oszacowania błędu wynika
istnienie liczby p takiej, że | p |< u i spełniającej następującą równość:
fl(a) = a(l+ /?)).
Zatem można powiedzieć, że przybliżona wartość fł(a) jest równa nieco znie-
kształconej (w wyniku pomnożenia jej przez liczbę bliską jedynce) wartości do-
kładnej liczby a.
Błąd względny daje ważną informację o liczbie przybliżonej. Wyjaśnia to
następujący przykład.
Przykład 6.2. Przyjmijmy za a liczbę 3.526437 i policzmy błędy względne dla
kilku przybliżonych wartości a :
a
5a
3
526430
2
.0
io-6
3
.526400
1
.0
10~5
3
526000
1
2
io-4
3
520000
1
8
10-3
3
500000
0
8
?IO-2
3
000000
1
5
io-1
Z tego przykładu wynika, że jeśli błąd względny ba liczby przybliżonej a jest
w przybliżeniu równy 10~n, to liczby a i a mają takie same n pierwszych cyfr
I znaczących w mantysie. I na odwrót, jeśli liczba a i jej przybliżenie o mają takie
same n pierwszych cyfr znaczących w mantysie, to błąd da jest w przybliżeniu
równy lQ-n.
13 Elementy informatyki
194
6. Metody numeryczne
Jak już wspomnieliśmy, wyniki działań na liczbach w reprezentacji zmiennopo-
zycyjnej, a więc w języku Pascal na liczbach typu REAL, są obarczone błędami za-
okrągleń. Zakłada się, że wyniki podstawowych działań arytmetycznych spełniają
następujące równości:
fl(a 6) =
fl(o/6) =
fl(a + 6) =
b(l
P2)/b,
6(1
gdzie | pi \< u, i = 1,2,3,4. Powyższe zależności należy rozumieć następu-
jąco: zmiennopozycyjny iloczyn jest równy dokładnemu iloczynowi nieco znie-
kształconych czynników a i 6(1 + pi). Podobnie iloraz jest równy dokładnemu
ilorazowi nieco zniekształconej dzielnej a(\ + p2) i b. Zmiennopozycyjna suma jest
równa dokładnej sumie nieco zniekształconych składników a(l + P3) i 6(1 + pi).
Wyniki podstawowych działań arytmetycznych w większości mikrokompu-
terów spełniają zależności (6). Z nich można łatwo wyprowadzić wzory na błędy
względne dla poszczególnych działań.
Dla mnożenia i dzielenia mamy:
ab - fl(a6)
ab
a/b - fl(a/6)
a/b
Natomiast dla dodawania otrzymujemy
= 1 P\ \P2 |< U.
{a + 6) - fl(a + b)
(a + b)
P3
a I + 6
a + b
-u.
Z powyższych wzorów wynika, że operacje mnożenia i dzielenia wprowadzają
błędy względne nie przewyższające względnej dokładności komputera u. Nato-
miast dodawanie liczb o różnych znakach (czyli ich odejmowanie) może wpro-
wadzić bardzo duży błąd względny, w przypadku gdy a + b jest małą liczbą.
Prześledźmy to na przykładzie.
Przykład 6.3. Dane liczby a = 13.128327726 i 6 = 13.128327789 zapisujemy
jako liczby zmiennopozycyjne z dziesięciocyfrową mantysą:
a = fl(o) = 0.1312832773 102, 6 = fł(6) = 0.1312832779 102.
Błędy względne liczb przybliżonych
Sa =
a a
4 ? 10~n 102
13.128327726
6.3. Schemat Hornera. Wzory rekurencyjne
195
6b =
b-b
10
-ii
102
13.128327789
< 10
-10
są mniejsze od u = 5-10 10. Natomiast błąd względny różnicy zmiennopozycyjnej
spełnia nierówność
(b - a) - fl(6 - a)
b a
6.3 - 10"10 ? 102 - 6 - 10~10 102
6.3 ? 10"10 102
> 4- 10"2.
Stąd wynika, że przy odejmowaniu liczb mało różniących się między sobą
występuje znaczny wzrost błędu względnego. Należy ten fakt mieć na uwadze
przy projektowaniu algorytmów numerycznych.
6.3. Schemat Hornera. Wzory rekurencyjne
Jednym z często rozwiązywanych zadań numerycznych jest obliczanie wartości
wielomianu. Wynika to z ważnego faktu matematycznego, zgodnie z którym
każdą funkcję ciągłą, nawet o najbardziej skomplikowanej postaci, można lo-
kalnie zastąpić wielomianem, którego postać zależy od tego, jaką chcemy uzy-
skać dokładność obliczeń i oczywiście od samej funkcji. Dla przykładu, wartości
niektórych standardowych funkcji w języku Pascal są obliczane jako wartości od-
powiednio dobranych wielomianów lub ilorazów wielomianów.
Przedstawimy teraz schemat Hornera, jeden z fundamentalnych algorytmów
numerycznych, który służy do obliczania wartości wielomianów. Można go także
znaleźć w metodach rozwiązywania wielu innych zadań numerycznych. Za jego
pomocą zilustrujemy ważną klasę zależności matematycznych zwanych wzorami
rekurencyjnymi, które znajdują wiele zastosowań w informatyce.
Naszym zadaniem jest obliczenie wartości wielomianu
wn(x) =
a\x
n-1
dla ustalonej wartości argumentu x = z.
Wyznaczmy najpierw liczbę dodawań
(7)
mnożeń potrzebnych do obliczenia
wn(z) ze wzoru (7). Dla obliczenia kolejnych potęg z , z ,..., zn należy wykonać
nl mnożeń. Następnie potrzeba n mnożeń, by obliczyć wartości jednomianów
a{Zn~l dla i = 0,1,..., n 1, i n dodawań, aby je zsumować. Zatem obliczenie
wartości wielomianu ze wzoru (7) wymaga wykonania In 1 mnożeń i n dodawań.
Wielomian (7) można przedstawić w innej postaci sugerującej odmienny spo-
sób liczenia jego wartości. Pokażemy to najpierw na przykładzie wielomianu
stopnia 3, który można zapisać następująco:
= ((clqx + ai)x + a2)x + a3.
196
6. Metody numeryczne
Postać ta podpowiada następujący sposób obliczania wartości wz(z):
bo = ao,
b\ = boz + ai,
62 = b\z + a-i,
h = b2Z + a3.
Szukaną wartością wielomianu jest 63. Zauważmy, że z wyjątkiem pierwszego
kroku w każdym następnym są wykonywane te same działania: mnożenie po-
przedniej wartości b przez z i dodanie do tego iloczynu kolejnego współczynnika
wielomianu. Możemy uogólnić tę obserwację i zastosować do wielomianu dowol-
nego stopnia. Otrzymamy wtedy następującą postać wielomianu:
wn(x) = (? ?
a\)x + a2)x
an-i)x + an
(8).
i odpowiadający jej sposób obliczania wartości dla argumentu z, zwany schema-J
tem Homera
60 = a0,
bi = bi\z + aj, i = 1,2,... ,71,
Liczba działań arytmetycznych potrzebnych do obliczenia wartości wielomianu
za pomocą schematu Homera wynosi n mnożeń i n dodawań, a więc jest on-1
mnożeń mniejsza niż w przypadku stosowania metody bezpośredniej, wynikającej j
z postaci (7).
Wzory (9) są przykładem zależności rekurencyjnej, którą tworzą współczyn-'
niki b: kolejny współczynnik bi oblicza się korzystając z wartości poprzedniegoj
współczynnika 6j_i, a współczynnik bo jest równy ac.
Przy okazji omawiania schematu Homera podkreślmy, że jednym z ważniej-"'
szych elementów w projektowaniu wielu algorytmów jest rekurencyjny opis rozwa-'
żanego zadania, oczywiście, jeśli taki opis jest możliwy. Nieraz długie obliczenia
można przedstawić w zwarty sposób za pomocą krótkich wzorów rekurencyjnychj
przyjmujących postać yn+i = F{Vn)- W czasie obliczeń, będących realizacją
takiej zależności każda wielkość yn występuje najpierw po lewej stronie, gdy jest
obliczana jej wartość, a następnie po prawej stronie, gdy służy do obliczenia
wartości yn+x-
Schemat Homera jest nie tylko bardzo efektywną metodą numeryczną pod
względem liczby wykonywanych działań arytmetycznych, ale także ma bardzo
prosty opis w języku Pascal. Zapiszemy go w postaci funkcji niestandardowej
Homer, której wartością jest wn(z). Dodatkowym wynikiem działania tej funkcji
jest tablica współczynników b.
6.3. Schemat Hornera. Wzory rekurencyjne
197
Na użytek funkcji i procedur występujących w tym rozdziale zdefiniujmy naj-
pierw następującą stałą i typ danych:
CONST NMax=50;
TYPE TablicaOn=ARRAY[O. .Max] OF REAL;
FUNCTION Horner(n:INTEGER;a:TablicaOn;z:REAL;
VAR b:TablicaOn):REAL;
{Wartością funkcji jest wartość wielomianu w postaci (7)
dla argumentu z obliczona za pomocą schematu Hornera (9).}
VAR i:INTEGER;
BEGIN
b[0]:=a[0];
FOR i:=l TO n DO
Horner:=b[n]
END; {Homer}
Uwaga: Tekst funkcji Horner znajduje się na dyskietce w pliku HDRNER.PAS umieszczo-
nym w kartotece R0ZDZ6.
Wielkości 6j występujące we wzorach (9) mają bardzo ciekawą interpretację.
Pozostawiamy do sprawdzenia, że prawdziwa jest następująca równość
X Z
(10)
Wn{x) n_1 n_2
x z
Wynika z niej, że wyrazy 6, są współczynnikami ilorazu
1JJ __-| I ^ J ^zz Qf\X i O~\ X ~T" ~T~ w 1
otrzymanego z dzielenia wielomianu wn(x) przez dwumian (x z), &bn jest resztą
z tego dzielenia.
Kolejną zależność, jaką spełniają współczynniki 6j, otrzymujemy mnożąc obie
strony równości (10) przez (x z), różniczkując obustronnie i podstawiając z
w miejsce x. Po lewej stronie dostajemy w'n(z), a po prawej pozostaje tylko
wn-i(z). Zatem jest spełniona równość
w'n(z) = wn-i(z).
(U)
Wynika stąd prosty sposób obliczania wartości wielomianu i jego pochodnej
dla tego samego argumentu z. Należy wykonać następujące czynności:
1. Obliczyć wartość wielomianu wn(z) stosując schemat Hornera. Jako dodat-
kowy wynik otrzymujemy ciąg liczb bo, b\,..., bn-\.
2. Stosując ponownie schemat Hornera, obliczyć wartość wielomianu o współ-
czynnikach 6q> fri> ? ) bn-\, która jest równa w'n(z).
198
6. Metody numeryczne
6.4. Stabilność algorytmów
Wiemy już, że każda operacja arytmetyczna na liczbach typu REAL może wprowa-
dzić błędy spowodowane zaokrągleniami argumentów i wyników działań. Zada-
nia numeryczne wymagają na ogół wykonania setek tysięcy działań. Jeśli każde
z nich lub przynajmniej znaczna ich część wprowadza błędy zaokrągleń, to mogą
się one kumulować (tzn. sumować) i powodować powstawanie zauważalnych znie-
kształceń wyników. W takim przypadku mówimy, że algorytm jest niestabilny.
Natomiast algorytm jest stabilny, jeśli w trakcie jego wykonywania nie dochodzi
do niekontrolowanej kumulacji błędów zaokrągleń. Obliczenia numeryczne mają
sens jedynie w przypadku stosowania algorytmów stabilnych.
6.4.1. Pierwiastki równania kwadratowego
Zakładając, że a ^ 0 możemy sprowadzić równanie (1), tj. ax2 + bx + c = 0 do
~2
postaci
px + q = 0
(12)
wygodniejszej w dalszych rozważaniach. Jeśli równanie (12) ma dwa różne pier-
wiastki, to oblicza się je ze znanych wzorów
(13)
Przyjmijmy, że obliczenia są wykonywane w arytmetyce 4-cyfrowej (tzn. z 4-
cyfrową mantysą), a współczynniki równania są równe p = 6.433 i q = 0.009474.
Obliczanie pierwiastka x\ może przebiegać następująco:
1. a = fl[(6.433)2] = 41.38,
2. (3 = fl[4 (0.009474)] = 0.03790,
3. 7 = fl(a -P) = 41.34,
4. a = fl(/y) = 6.430,
5.
Dokładna wartość pierwiastka, zaokrąglona do pięciu cyfr, jest natomiast
równa 1.47310-10~3. Zatem obliczona wartość x\ zgadza się z dokładną wartością
tylko na pierwszej cyfrze, czyli błąd względny przybliżenia wynosi około 10"1.
Obliczmy teraz wartość drugiego pierwiastka. Początkowe obliczenia są takie
same jak w krokach 1-4, a dalej otrzymujemy
5'. tp' = fl(6.433 + a) = 12.86,
x2 = fl(v'/2) = 6.430.
6.4. Stabilność algorytmów
199
Dokładna wartość pierwiastka X2, zaokrąglona do pięciu cyfr, wynosi 6.4313.
Zatem obliczona wartość ?2 jest zgodna z dokładną wartością na trzech cyfrach
znaczących, czyli błąd przybliżenia wynosi około 10 . Jeśli a jest przybliżeniem
znormalizowanej liczby zmiennopozycyjnej a, to fc-tą cyfrę po kropce w liczbie a
nazywamy cyfrą znaczącą wtedy, gdy \ a a \< 0.5 10~fc.
Dokładność pierwszego pierwiastka można zwiększyć korzystając ze wzoru
Viete'a
x\ ? X2 = q-
W naszym przypadku otrzymujemy
xi = fl(g/ś2) = fl(0.009474/6.430) = 0.001473 = 1.473 10
-3
Obliczona wartość pierwiastka jest więc zgodna z dokładną wartością x\ na czte-
rech miejscach, czyli błąd względny przybliżenia jest równy około 10~4.
Powodem utraty dokładności obliczeń pierwiastka x\ jest odejmowanie dwóch
bliskich sobie liczb, 6.433 i 6.430, w kroku 5. Natomiast w kroku 5', gdzie te same
dwie liczby są dodawane, dokładność utrzymuje się na dobrym poziomie.
Z dotychczasowych rozważań możemy wyciągnąć następujący wniosek o sto-
sowaniu wzorów (13): jeśli p > 0, to pierwiastek x\ jest liczony z większą
dokładnością niż X2, natomiast dla p < 0 dokładniej będzie obliczony X2- Otrzy-
mujemy stąd stabilny algorytm znajdowania pierwiastków równania kwadrato-
wego, który zapiszemy poniżej w postaci procedury w języku Pascal. W pro-
cedurze tej uwzględniamy także przypadek, gdy równanie nie ma pierwiastków
rzeczywistych.
PROCEDURĘ Rownanie2(p,q:REAL;VAR Del:B00LEAN;VAR xl,x2:REAL);
{Procedura oblicza z jednakowa dokładnością pierwiastki
rzeczywiste równania kwadratowego (12). Zmienna Del
przyjmuje wartość TRUE, jeśli równanie ma pierwiastki
rzeczywiste, i FALSE - w przeciwnym przypadku.}
VAR Delta:REAL;
BEGIN
Delta:=p*p-4*q;
Del:=Delta>=0;
IF NOT Del THEN EXIT;
Delta:=SQRT(Delta);
IF p<0 THEN BEGIN
x2:=(-p+Delta)/2;
xl:=q/x2
END
ELSE BEGIN
200
6. Metody numeryczne
xl:=(-p-Delta)/2;
x2:=q/xl
END
END; {Rownanie2}
Uwaga: Tekst procedury Rownanie2 znajduje się na dyskietce w pliku RÓWNANIE.PAS
umieszczonym w kartotece R0ZDZ6.
Procedura EXIT działa podobnie jak procedura STOP w języku Logo.
W zadaniu 6.6 zachęcamy do napisania procedury będącej bezpośrednią rea-
lizacją wzorów (13) i porównania wartości pierwiastków otrzymanych obydwoma
sposobami rozwiązywania równania kwadratowego.
6.4.2. Układ dwóch równań liniowych
Omówimy teraz inne zadanie, by pokazać, że mimo użycia algorytmu stabil-
nego można otrzymać rozwiązanie dość poważnie zniekształcone błędami. Źródło
błędów leży teraz nie w użytej metodzie rozwiązywania a w samym zadaniu.
Należy znaleźć rozwiązanie układu
= a2ja\ i odejmijmy od
- b2y = c2.
W tym celu pomnóżmy pierwsze równanie przez di
drugiego równania. Otrzymamy wówczas
(14)
Dla współczynników a\ = 3.000, bx = 4.127, ci = 15.41, a2 = 1.000, b2 =
1.374, c2 = 5.147 dokładnym rozwiązaniem są liczby x = 13.6658 i y = 6.2.
Podobnie jak w poprzednim przykładzie wartość y wyznaczymy wykonując
obliczenia w arytmetyce 4-cyfrowej:
1. a = fl(15.41/3) = 5.137,
2. /? = fl(5.147-ev) = 0.010,
3. 7 = fl(4.127/3) = 1.376,
4. a = fl(1.374 - 7) = -0.002,
y = fl(/?/
względnym spełniającym nierówność
6y =
-6.2 + 5
-6.2
1.2
6.4. Stabilność algorytmów
201
Przyczyną powstania tak dużego błędu w powyższych obliczeniach jest utrata
dokładności w krokach 2 i 4, gdzie są odejmowane od siebie bliskie co do wartości
liczby. Czy oznacza to, że zastosowany algorytm jest niestabilny? Niezupełnie.
Metoda, jaką użyliśmy do wyznaczania wartości niewiadomej y, jest szczególnym
przypadkiem tak zwanej eliminacji Gaussa, o której wiadomo, że jest algoryt-
mem stabilnym. Cóż więc się zdarzyło? Otóż dla podanych wartości współczyn-
ników otrzymaliśmy układ równań źle uwarunkowany. Oznacza to, że dla tego
zadania każdy algorytm wyznaczy rozwiązanie obarczone dużymi błędami. Nie
będziemy wyjaśniać, jakie jest pełne znaczenie złego uwarunkowania. W przy-
padku układu dwóch równań istnieje jednak proste geometryczne wytłumaczenie
zaistniałych trudności.
Rozwiązywany układ równań reprezentuje dwie przecinające się proste. Moż-
na sprawdzić, że te proste przecinają się pod bardzo małym kątem, równym około
0.036 stopnia. Rozwiązaniem tego układu są współrzędne punktu P przecięcia
się prostych. Przyjmijmy, że te proste są narysowane kreską o grubości równej
względnej dokładności obliczeń, tzn. 5 ? 10~4. Ze względu na to, że kąt między
prostymi jest mały, punkt P jest rozmyty i niezbyt widoczny na rysunku. Nie
jest on także dobrze widoczny dla algorytmu, liczącego z dokładnością do 4
cyfr dziesiętnych. Oczywiście, punkt ten można wyznaczyć dokładniej, stosując
dokładniejszą arytmetykę np. 10-cyfrową. Ale i wtedy otrzymane rozwiązanie,
chociaż dokładniejsze niż w przypadku stosowania arytmetyki 4-cyfrowej, będzie
miało mniej niż 10 cyfr dokładnych.
Podkreślmy wyraźnie, że złe uwarunkowanie jest własnością zadania, a nie
algorytmu rozwiązującego to zadanie.
6.4.3. Usuwanie niestabilności w obliczeniach
Rozważmy jeszcze jeden przykład ilustrujący dość zaskakujący sposób zachowania
się błędów zaokrągleń w obliczeniach numerycznych.
Należy obliczyć wartości następującej całki oznaczonej
Vn =
dx
(15)
dla n = 1, 2,..., 8. Zauważmy, że wartość tej całki jest dodatnia dla każdego
n, gdyż funkcja podcałkowa jest dodatnia w przedziale (0,1). Ponadto zachodzą
następujące zależności
Vn - J/n+1 =
1 xn
xn(l-x)
dx > 0.
202
6. Metody numeryczne
Zatem ciąg liczbowy {yn} jest ciągiem malejącym o wyrazach dodatnich. Łatwo
sprawdzić, że prawdziwy jest następujący wzór rekurencyjny (por. zad. 6.3)
yn = l/n - 5yn-i.
Z tego wzoru wynika następujący algorytm obliczania wartości yn:
1. Obliczyć 2/0 korzystając ze wzoru (15):
(16)
dx
2 + 5
\l= 0.182.
2. Obliczyć kolejno 2/1,2/2, , 2/8 z wzoru rekurencyjnego (16).
Wyniki obliczeń tym algorytmem w arytmetyce 3-cyfrowej są następujące:
3/1 = 1 5y0 = 0.090,
2/2 = 0.050,
V3 = 0.083,
2/4 = -0.165,...
Zauważmy, że wartości już pierwszych wyrazów ciągu są błędne: 2/3 jest]
większe od 2/2, a 2/4 jest ujemne. Wyjaśnijmy przyczynę tak złego działania algo-J
rytmu. Każde zaokrąglenie liczby do trzech cyfr znaczących powoduje powstani^
bezwzględnego błędu zaokrąglenia równego około 0.5 10~3. Zatem 2/0 jest obar-1
czone błędem e takim, że | e |< 0.5-10~~3, to znaczy 2/0 = 0.182 + e. Ze wzoru (16)
dlań = 1 obliczamy wartość 2/1 = 1 5yo = 1 5(0.182+e) = 0.090+5e, która jest!
już obarczona błędem 5e, czyli pięć razy większym. Licząc dalej, otrzymujemy g/2}
z błędem 25e i 2/4 z błędem 625e, równym w przybliżeniu 0.3125. Zatem algorytm I
będący realizacją wzoru (16) powoduje w każdym kroku zwielokrotnienie błędu j
wytworzonego w poprzednim kroku.
Odwróćmy teraz zależność rekurencyjną (16) tak, byśmy mogli liczyć wyrazy ]
yn od końca:
-yn/h. (17)1
Moglibyśmy skorzystać z tego wzoru, gdyby znane były wartości 2/8 lub
Aby temu jakoś zaradzić, skorzystajmy z faktu, że {yn} jest ciągiem malejącymi
o wyrazach dodatnich. Ciąg taki jest zbieżny, a zatem dostatecznie dalekie jego
wyrazy są sobie bliskie. Możemy więc założyć, że z pewną dokładnością zachodzi I
równość 2/9 = 2/io- Następnie użyjmy wzoru (16) do obliczenia 2/9 i skorzystajmy'
z zależności (17), by policzyć interesujące nas wyrazy. Otrzymujemy wówczas
2/9 = 0.017, 2/6 = 0.025, j/3 = 0.043, yQ = 0.182,
2/8 = 0.019, j/5 = 0.028, y2 = 0.058,
2/7 = 0.021, 2/4 = 0.034, yx = 0.088,
6.5. Interpolacja
203
Zauważmy, że w ten sposób otrzymaliśmy poprawną (z dokładnością do 3 cyfr)
wartość j/o- Sukces ten można wytłumaczyć tym, że w obliczeniach prowadzonych
zgodnie z wzorem (17), błędy zaokrągleń w każdej iteracji są dzielone przez 5.
Mamy zatem do czynienia w tym przypadku ze zjawiskiem tłumienia błędów
zaokrągleń. Dzięki temu algorytm ten jest stabilny.
Przykład ten pokazuje, że niektóre zależności, chociaż matematycznie równo-
ważne, mogą mieć przeciwstawne własności numeryczne.
6.5. Interpolacja
Wiele zjawisk w przyrodzie daje się opisać za pomocą zależności funkcyjnych.
Dobrze są znane takie zależności w fizyce. Jest bardzo dobrze, jeśli zależność
taka jest opisana za pomocą konkretnej funkcji danej wzorem analitycznym.
Wówczas opisane zjawisko można dokładnie i wszechstronnie analizować, badając
funkcję z nim związaną. Istnieją jednakże takie zjawiska, które nie dają się opisać
dokładnymi zależnościami funkcyjnymi. Wówczas informacje o nich uzyskuje się
z pomiarów. Przypuśćmy, że interesuje nas stężenie zanieczyszczeń jako funkcja
odległości od ich źródła, którym jest dymiący komin fabryczny. W tej sytuacji
możemy jedynie pomierzyć stężenie zanieczyszczeń w różnych odległościach od
źródła i otrzymać następującą tablicę opisującą tę nieznaną funkcję:
X
Xq
Xl
Xl
.. xn
f
/o
h
h ?
gdzie Xi jest odległością od źródła zanieczyszczeń mierzoną w metrach, a fi jest
stężeniem zanieczyszczającej substancji mierzonym w g/m2. Wygodniej byłoby
mieć jawną zależność funkcyjną f(x), ale z kilkunastu czy nawet z kilkudziesięciu
pomiarów zależności tej nie da się odtworzyć. Można natomiast zbudować inną
funkcję, która niedużo będzie różniła się od poszukiwanej. Takich funkcji jest
wiele. My ograniczymy swoją uwagę tylko do wielomianów n-tego stopnia wn(x)
jako funkcji przybliżających, które powinny spełniać warunki
wn(xi) = fi, i = 0, l,...,n,
(18)
zwane warunkami interpolacji. Liczby Xi nazywamy węzłami interpolacji i
zakładamy, że są parami różne oraz uporządkowane rosnąco lub malejąco (jeśli ten
drugi warunek nie jest spełniony, to podany dalej algorytm może być niestabilny).
Wielomian wn nazywamy wielomianem interpolacyjnym. Znanych jest wiele
sposobów konstruowania wielomianów interpolacyjnych. Tutaj zajmiemy się
zbudowaniem wielomianu interpolacyjnego Newtona w postaci
204
6. Metody numeryczne
wn(x) =
-xi)... (x-xn-\)
Współczynniki c w tym wzorze można wyznaczyć korzystając z warunków
(18). Obliczymy kilka początkowych z nich. Dla x = xo otrzymujemy natych-
miast
co = /o-
Dla x = x\ otrzymujemy
h =
-x0),
skąd
ci =
fi-fo
xi -x0
Oznaczmy tę ostatnią wielkość przez /oi. Obliczmy jeszcze c2- W tym celu pod-
stawmy X2 w miejsce x w wielomianie interpolacyjnym Newtona i skorzystajmy
z warunków (18). Otrzymamy
/2 = /o + (X2 - XO)foi + C2(x2 - X0)(X2 - Xl).
Po podzieleniu obu stron przez (x2 Xo)(x2 xi) mamy
/2-/0
(X2 -
___1_
1
X2 i
-foi;
fi fi fo
--------------1------------------
/12 + /(
X2 Xo
X2 - Xi
Ol
X2 Xl
-/or
X2 - Xi
/oi
x2 -
= /012-
Wielkości /o, /oi, /oi2i ? jakie pojawiają się we wzorach na kolejne współ-
czynniki Ci nazywają się ilorazami różnicowymi odpowiednio zerowego, pierw-
szego, drugiego itd. rzędu. Można je łatwo obliczyć za pomocą następującego)
wzoru rekurencyjnego
Xk-Xi
który umożliwia obliczanie ilorazów różnicowych dowolnego rzędu p + 1 za po
mocą dwóch ilorazów różnicowych rzędu p. Jest to proces, który można łato
zautomatyzować korzystając z następującej tablicy
6.5.Interpolacja
205
/o
h
/oi
"0123
Każdy element tej tablicy, poczynając od trzeciej kolumny, jest obliczany ze
wzoru (19) według schematu zaznaczonego strzałkami.
Można wykazać indukcyjnie, że
Ci = /oi2...i, i = 0,1,2,..., n,
a zatem wielomian interpolacyjny Newtona przyjmuje ostatecznie postać
n{x) = /o
(x - Xj_l
(20)
Przykład 6.4. Korzystając z powyższych wzorów, zbudujemy wielomian interpo-
lacyjny Newtona trzeciego stopnia spełniający warunki: W3(2) = 2, 7i>3(0) = 2,
U)3(l) = 4, ws(2) = 6. Tworzymy najpierw tablicę ilorazów różnicowych
2
2
0
2
0
1
-4
-6
-2
2
-6
-2
2 1
ej
odczytujemy:
co
= /o =
2,
c\
= /oi =
= 0,
ci
= /012 :
= -2,
C3
= /oi23
= 1.
Z wzoru (20) otrzymujemy
w3(x) = 2 + 0(a; + 2) - 2(a; 4- 2)x + l(x + 2)x{x - 1).
Po przekształceniu wielomian można zapisać w postaci
w3(x) = x3 - x2 - 6x + 2.
Wielomian interpolacyjny zbudowany dla funkcji danej w postaci tablicy jej
wartości można uznać za przybliżoną postać analityczną tej funkcji. ?
206
6. Metody numeryczne
Poniższa procedura InterNewton umożliwia skonstruowanie wielomianu in-
terpolacyjnego Newtona (20) dla n+1 wartości funkcji i węzłów danych odpowie-
dnio w tablicach c i x. Węzły interpolacji mogą należeć do ustalonego przedziału
i być w nim równo rozmieszczone - nie są to jednak warunki konieczne dla po-
prawnego działania tej procedury. Obliczone współczynniki wielomianu interpo-
lacyjnego zostają umieszczone w tablicy c.
PROCEDURĘ InterNewton(n:INTEGER;x:TablicaOn;VAR c:TablicaOn);
{Procedura oblicza współczynniki c[i] wielomianu interpola-
cyjnego Newtona (20), spełniającego warunki (18) dla war-
tości funkcji f i wezlow interpolacji umieszczonych odpo-
wiednio w tablicach c i x.}
VAR i,k:INTEGER;
BEGIN
FOR k:=i TO n DO
FOR i:=n DOWNTO k DO
[
END; {InterNewton}
I ; | Uwaga: Tekst procedury InterNewton znajduje się na dyskietce w pliku INTERNEW.PAS
umieszczonym w kartotece R0ZDZ6.
Podana niżej funkcja oblicza wartość wielomianu interpolacyjnego Newtona
(20) za pomocą odpowiednio dostosowanego schematu Homera.
FUNCTION InterHorner(n:INTEGER;x,c:TablicaOn;z:REAL):REAL;
{Wartością funkcji jest wartość wielomianu interpolacyjnego
Newtona (20), o współczynnikach i węzłach umieszczonych
odpowiednio w tablicach c i x.}
VAR i:INTEGER;
v:REAL;
BEGIN
v:=c[n] ;
FOR i:=n-l DOWNTO 0 DO
v:=v*(z-x[i])+c[i];
InterHorner:=v
END; {InterHorner} ,
Uwaga: Tekst procedury InterHorner znajduje się na dyskietce w pliku INTERHOR.PAS
umieszczonym w kartotece R0ZDZ6.
Najważniejszym zagadnieniem rozważanym w przypadku stosowania interpo-
lacji jest skuteczność (mówimy także, dobroć) przybliżania nieznanej funkcji
przez wielomian interpolacyjny, zbudowany na podstawie pewnej liczby wartości
6.5. Interpolacja
207
funkcji otrzymanych w określonych punktach. Jeśli interpolowana funkcja jest
rzeczywiście nieznana, to trudno jest ocenić tę dobroć. Można natomiast przepro-
wadzić testy i oceniać dobroć wielomianu interpolacyjnego na podstawie obliczeń
wykonanych dla znanych funkcji. Poświęcimy temu resztę uwagi w tym punkcie.
Zaobserwujmy najpierw na przykładzie, jakie może być wzajemne położenie wy-
kresów funkcji i jej wielomianu interpolacyjnego wn (zob. rys. 6.1). Funkcją jest
j[x) = 0.5 sin a: + 2, a wielomian wn ma stopień 5 i otrzymano go w przedziale
[a,b] = [0.3,9.9] (porównaj wyniki zamieszczone w przykładzie 6.5).
xi = 2.2 x2 = 4.1 x3 = 6.1 x4 = 8.0
Rys. 6.1. Funkcja i jej wielomian interpolacyjny
= 9.9 x
Z rysunku 6.1 możemy odczytać, że w węzłach interpolacji xq, x\, ..., xn
są spełnione równości f(xi) = wn(xi), a w pozostałych punktach przedziału [a, b]
wartości funkcji i wielomianu mogą się różnić dość znacznie. Natomiast poza
przedziałem [a, b] te różnice mogą być dowolnie duże.
Moduł (czyli wartość bezwzględna) największej różnicy wartości funkcji i wie-
lomianu w przedziale [a, b] możemy uznać za miarę odległości między funkcją
/ a wielomianem wn, i oznaczamy przez p(f,w) :
p(f,w) = max \f{x) - wn(x)\.
xe[a,b]
Wielkość ta charakteryzuje skuteczność przybliżania danej funkcji / wielo-
mianem interpolacyjnym wn w przedziale [a,b]. Przybliżoną wartość odległości
p wyznaczoną na podstawie 128 punktów w przedziale [a, b] oblicza następująca
funkcja:
208
6. Metody numeryczne
FUNCTION RoFW(n:INTEGER;a,b:REAL;x,c:TablicaOn):REAL;
{Wartością funkcji jest przybliżona wartość odległości
Ro(f,w) pomiędzy nielokalna funkcja f i jej wielomianem
interpolacyjnym Newtona (20) w przedziale [a,b]. Węzły
interpolacji i współczynniki wielomianu sa umieszczone
odpowiednio w tablicach x i c. Funkcja RoFW korzysta
z funkcji InterHorner.}
CONST m=128;
VAR t,h,Max,r:REAL;
BEGIN
h:=(b-a)/m; t:=a;
Max:=ABS(InterHorner(n,x,c,t)-f (t));
REPEAT
t:=t+h;
r:=ABS(InterHorner(n,x,c,t)-f(t));
IF Max
RoFW:=Max
END; {RoFW}
I '. J Uwaga: Tekst funkcji RoFW znajduje się na dyskietce w pliku ROFW.PAS Umieszczonym
w kartotece R0ZDZ6.
Rozważmy teraz następujące zadanie obliczeniowe. Dla danej funkcji / zbu-
dować wielomian interpolacyjny wn w przedziale [a, b] na n + 1 równoodległych
węzłach i obliczyć odległość p(f, w). Na ekran wyprowadzić następujące wyniki: j
stopień wielomianu n, węzły Zj, współczynniki Cj oraz odległość p(f,w).
Sformułowane wyżej zadanie realizuje program Testlnterpolacji1.
{$N-}
PROGRAM Testlnterpolacji;
USES CRT;
CONST NMax=50;
TYPE Tablica0n=ARRAY[0..NMax] 0F REAL;
VAR a,b:REAL;
n :INTEGER;
x,c:TablicaOn;
*Na początku tego programu pojawia się po raz pierwszy w naszych programach w języj
Turbo Pascal dyrektywa (tutaj N-), która odgrywa rolę wskazówki uwzględnianej przez syst(
TP w czasie tłumaczenia lub działania programu. Dyrektywa W- jest żądaniem wykonania otj
czeń na wartościach typu REAL bez użycia procesora numerycznego, nawet jeśli jest zainstakra
w komputerze. Dokładniejsze omówienie znaczenia dyrektyw można znaleźć w podręczn
dotyczących systemu TP.
6.5. Interpolacja
209
FUNCTION f(x:REAL):REAL;
BEGIN
f :=0.5*SIN(x)+2
END;
{W tym miejscu należy umieścić opisy procedury InterNewton
i funkcji InterHorner oraz RoFW zdefiniowane powyżej.}
PROCEDURĘ CzytajDane(VAR n:INTEGER; VAR a,b:REAL);
VAR Error:B00LEAN;
BEGIN
WRITELN;
WRITELNCDane:');
WRITELN(' 0
WRITELN;
REPEAT
WRITE('n='); READLN(n);
Error:=(n<=0) DR (NMax
REPEAT
WRITE('a='); READLN(a);
WRITE('b='); READLN(b);
Error:=a>=b;
IF Error THEN WRITELN('Musi byc: aUNTIL NOT Error
END; {CzytajDane}
PROCEDURĘ PrzygotujDane(VAR x,c:TablicaOn);
VAR i :INTEGER;
y,h:REAL;
BEGIN
h:=(b-a)/n; y:=a;
FOR i:=0 TO n DO BEGIN
x[i] :=y;
c[i]:=f(y);
y:=y+h
END
END; {PrzygotujDane}
PROCEDURĘ Wyniki;
VAR i:INTEGER;
BEGIN
14 Elementy informatyki
210
6. Metody numeryczne
WRITELN;
WRITELN('Stopień wielomianu interpolacyjnego n=',n,'.');
WRITELN;
WRITELNC Wezly x[i] Współczynniki c[i]');
WRITELN(J i interpolacji wielomianu');
WRITELN ( '--------------------------------------' ) ;
FOR i:=0 TO n DO
WRITELN(i:2,' ',x[i]:12:8,' ',c[i] :12:8);
WRITELNC--------------------------------------------------------------');
WRITELN('Odległość Ro=',RoFW(n,a,b,x,c):10);
WRITELN
END; {Wyniki}
BEGIN {Testlnterpolacji}
CLRSCR;
CzytajDane(n,a,b);
PrzygotujDane(x,c);
InterNewton(n,x,c);
Wyniki;
WRITECNacisnij dowolny klawisz');
REPEAT UNTIL KEYPRESSED
END. {Testlnterpolacji}
J~i~j Uwaga: Tekst programu Testlnterpolacji znajduje się na dyskietce w pliku i
TESTINT.PAS umieszczonym w kartotece R0ZDZ6.
Przykład 6.5. Wykonano obliczenia programem Testlnterpolacji dla funkcji)
f(x) = 0.5sina; + 2 oraz danych n = 5, a = 0.3, b = 9.9 i otrzymano wyniki:
Stopień wielomianu interpolacyjnego n=5.
Wezly x[i]
Współczynniki c[i]
i
interpolacji
wielomianu
0
0.30000000
2.14776010
1
2.22000000
0.13048054
2
4.14000000
-0.14500733
3
6.06000000
0.05174175
4
7.98000000
-0.00928560
5
9.90000000
0.00071257
Odległość Ro = 2.746E-01
6.6. Całkowanie numeryczne
211
6.6. Całkowanie numeryczne
Obliczanie wartości całki (2), czyli wartości Ja f(x) dx jest łatwe, gdy potrafimy
znaleźć funkcję pierwotną, tzn. taką funkcję F(x), że F'{x) f(x). Wówczas:
Na przykład,
/ir/2
k '
= F(x)\ba=F(b)-F{a)
/o
cos(x) dx sin(x) |0 = sin(7r/2) sin(O) = 1.
(21)
Na ogół dla całek o praktycznym znaczeniu w fizyce i w technice nie udaje się
wyznaczyć funkcji pierwotnej, a tym samym nie można stosować wzoru (21).
W sytuacji, gdy nie możemy skorzystać ze wzoru (21), całkę oznaczoną I
liczymy w sposób przybliżony, zwany całkowaniem numerycznym. Większość
wzorów całkowania numerycznego ma następującą postać zwaną kwadraturą:
i=O
Wielkości Ai, x\ oraz E nazywają się, odpowiednio, współczynnikami, węz-
łami i błędem kwadratury. By zdefiniować konkretną kwadraturę należy prze-
de wszystkim określić wartości tych wielkości. Podkreślmy tutaj, że sam błąd
kwadratury nie bierze udziału w numerycznym całkowaniu, a jest tylko informacją
o błędzie, jaki powstaje przy zastąpieniu całkowania sumowaniem, czyli dokładnej
wartości całki wartością sumy, która przybliża wartość całki.
Istnieje bardzo wiele sposobów wyznaczania kwadratur. Tutaj posłużymy się
rozumowaniem, opartym na geometrycznej interpretacji całki oznaczonej. Wia-
domo, że wartość całki (2) jest równa polu obszaru ograniczonego krzywą /(x),
osią Ox i prostymi x a oraz x = b. Dokładna wielkość tego pola jest równa
dokładnej wartości całki (2). Przybliżoną zaś wartość całki można otrzymać licząc
wielkość tego pola w sposób przybliżony. Jeden z takich sposobów, zwany kwa-
draturą trapezów, jest zilustrowany na rys. 6.2. W tej metodzie cały obszar
pod krzywą dzielimy na paski, każdy o ustalonej szerokości h, i obszar w każdym
pasku zastępujemy trapezem. Równoważnie fragment krzywej f(x) w każdym pa-
sku zastępujemy prostą interpolacyjną, która przechodzi przez punkty przecięcia
paska z krzywą. Cały obszar zostaje w ten sposób podzielony na trapezy o pod-
stawach fi = /(xj) oraz /j+i = /(xj+i), dla i = 0, l,...,m 1, które mają
jednakową wysokość h.
Pole i-tego trapezu jest równe h(fi + /j+i)/2, zatem sumując pola wszystkich
trapezów otrzymujemy kwadraturę, nazywaną złożonym wzorem trapezów
212
6. Metody numeryczne
a =
xi
Rys. 6.2. Ilustracja do wzoru trapezów
Ja
t=l
gdzie h = (b a)/m.
Z innych, nieco trudniejszych rozważań wynika, że dla E otrzymuje się wzór
12m2
gdzie 77 jest nieznaną liczbą z przedziału (a, b). Jeśli druga pochodna f"(x) jest
ograniczona w przedziale (a, b), tzn. jeśli istnieje stała M taka, że jest spełniony
warunek
f"(x) |< M
dla x e (a, 6), to dla błędu kwadratury otrzymujemy
nierówność
Zauważmy, że zwiększając m, czyli dzieląc przedział całkowania na coraz węższe
paski, powodujemy, że błąd kwadratury dąży do zera.
Dokładniejszą kwadraturę otrzymamy przybliżając fragment krzywej /(z)
nad dwoma sąsiednimi paskami wielomianem interpolacyjnym drugiego stopnia,
czyli parabolą. W tym przypadku m musi być liczbą parzystą. Otrzymujemy
6.6. Całkowanie numeryczne
213
wówczas złożony wzór Simpsona, który ma postać
f{x)dx= g(/o +
zie h = (b a)/m,
2/2 + 4/3 + . . .
2/m_2 + 4/m_!
Podamy teraz opis funkcji niestandardowej Simpson, której wartością jest
przybliżona wartość całki oznaczonej z funkcji f(x) w przedziale [a, b] podzielo-
nym na m podprzedziałów. Wzór trapezów pozostawiamy do samodzielnego za-
programowania i proponujemy porównać jakość przybliżeń otrzymywanych obie-
ma metodami (por. zad. 6.9).
FUNCTION Simpson(a,b:REAL;m:INTEGER):REAL;
{Wartością funkcji jest obliczona ze wzoru Simpsona przyb-
liżona wartość całki oznaczonej (2) z nielokalnej funkcji
f w przedziale [a,b].}
VAR k,i :INTEGER;
g,h,s,r:REAL;
BEGIN
{Liczba podprzedziałów we wzorze Simpsona jest parzysta.
Jeśli dana liczba m nie jest parzysta, to zwiększamy ja
o 1. Parzystość badamy za pomocą standardowej funkcji
boolowskiej DDD.}
IF ODD(m) THEN m:=m+l;
h:=(b-a)/m; k:=m DIV 2;
s:=0.0; g:=h;
FOR i:=l TO k DO BEGIN
s:=s+f(a+g);
g:=g+h+h
END;
r:=0.0; g:=h+h;
FOR i:=l TO k-1 DO BEGIN
r:=r+f(a+g);
g:=g+h+h
END;
Simpson:=h*(f(a)+4*s+2*r+f(b))/3
END; {Simpson}
Uwaga: Tekst funkcji Simpson znajduje się na dyskietce w pliku SIMPSON.PAS umie- I ; |
szczonym w kartotece R0ZDZ6.
214
6. Metody numeryczne
Przykład 6.6. Funkcja Simpson została użyta do obliczenia wartości całki ozna-
czonej
*['?-,. (22)
której dokładna wartość wynosi n = 3.1415926536. Wartości przybliżone otrzy-
mane dla różnych liczb podprzedziałów całkowania są podane w tablicy 6.1. I
Tablica 6.1. Przybliżone
wartości całki (22)
m
Wartość całki
2
3.1333333333
4
3.1415686274
6
3.1415917809
8
3.1415925025
10
3.1415926139
12
3.1415926403
14
3.1415926483
16
3.1415926512
18
3.1415926524
20
3.1415926530
22
3.1415926532
24
3.1415926534
28
3.1415926535
36
3.1415926536
6.7. Wyznaczanie pierwiastków równania
Na lekcjach matematyki są omawiane wzory na pierwiastki równania kwadrato-
wego. Następnie, przy omawianiu funkcji trygonometrycznych, są rozwiązywane
także równania zawierające te funkcje, ale najczęściej takie, które po odpowie-
dnim przekształceniu dają się sprowadzić do równań kwadratowych lub liniowych.
Natomiast nie było dotychczas mowy o równaniach w ogólnej postaci
f(x) = 0,
(23)
gdzie f(x) jest dowolną funkcją, ponieważ ich pierwiastki na ogół nie wyrażają
się zamkniętymi wzorami, a jeśli takie istnieją, to często są zbyt skomplikowane.
Równania (23) można dość łatwo rozwiązywać stosując odpowiednie metody
przybliżone. Najczęściej stosowane są metody iteracyjne przyjmujące postać
i = 0,1,...
6.7. Wyznaczanie pierwiastków równania
215
i
które dla danego przybliżenia początkowego xo wyznaczają ciąg kolejnych przy-
bliżeń xi,X2,X3,... przypuszczalnie zbieżny do pierwiastka a równania (23).
Zbieżność tego ciągu często zależy od wyboru przybliżenia początkowego. Na
ogól ?o musi leżeć dostatecznie blisko pierwiastka a. Dlatego wyznaczenie przy-
bliżenia początkowego jest ważnym elementem każdej metody iteracyjnej.
6.7.1. Przybliżenia początkowe
Początkowe przybliżenia pierwiastków równania (23) można otrzymać sporządza-
jąc tablicę wartości funkcji f(x) w przedziale [a, b], w którym spodziewamy się
istnienia pierwiastków.
Przykład 6.7. Postarajmy się znaleźć liczbę xq leżącą możliwie blisko pierwia-
stka równania (23) dla funkcji
f(x) = 0.25x2 - sin(ar).
W tym celu utwórzmy tablicę wartości tej funkcji w przedziale [1.6,2.2] dla ar-
gumentu zmieniającego się z krokiem 0.2:
1.6
1.8
2.0
2.2
-0.460 -0.164 0.091 0.399
Stąd odczytujemy, że w przedziale (1.8, 2.0) wartości funkcji f(x) zmieniają znak,
co oznacza, że w tym przedziale jest co najmniej jeden pierwiastek równania (23).
Jako xq możemy przyjąć środek tego przedziału, czyli Xq = 1.9. ?
Zaproponowane w powyższym przykładzie postępowanie jest słuszne dla funk-
cji ciągłych. Prawdziwe jest bowiem następujące twierdzenie:
Twierdzenie 6.1. Jeśli funkcja f(x) jest ciągła i /(a) ? f(b) < 0, to równanie
(23) ma co najmniej jeden pierwiastek w przedziale [a,b].
6.7.2. Metoda Newtona
Przyjmijmy, że znamy przybliżoną wartość z$ szukanego pierwiastka a. Przez
punkt A o współrzędnych (zź, f(xi)), leżący na krzywej /(z), prowadzimy styczną.
Styczna przecina oś Ox w punkcie o odciętej Zj+i, której wartość przyjmu-
jemy jako następne przybliżenie pierwiastka. Wyprowadźmy teraz wzór dla xi+\
(zob. rys. 6.3). Równanie stycznej do krzywej w punkcie A ma postać
f ( \ f1f\f \
__ + I ry . \ --- / I T1 llT1 __ T* 1
J y^ij J V fc/\ ^t)*
216
6. Metody numeryczne
Zatem odcięta
wzorem
Rys. 6.3. Ilustracja do metody Newtona
j+i punktu, w którym styczna przecina oś Ox wyraża się
i = 0,1,2,...
(24)
I
Powyższa metoda nazywa się metodą Newtona. Jest to metoda o dobrych
własnościach numerycznych.
Bardzo ważnym do rozstrzygnięcia problemem w metodach iteracyjnych jest
pytanie, kiedy przerwać obliczenia. Odpowiedź powinna oczywiście uwzględniać
dokładność pierwiastka, jaką chcemy osiągnąć. Do najczęściej stosowanych kry-
teriów zakończenia obliczeń należą:
- sprawdzenie, czy dwa kolejne przybliżenia Xi, Xi+x pierwiastka leżą dosta-
tecznie blisko siebie, tzn. czy spełniona jest nierówność
dla liczby e > 0. (Liczba e nie może być dowolnie mała, ponieważ ze
względu na ograniczoną dokładność obliczeń, w tym także błędy zaokrągleń,
powyższa nierówność mogłaby nie być nigdy spełniona.)
sprawdzenie, czy dwa kolejne przybliżenia Xi, Xi+\ pierwiastka leżą dosta-
tecznie daleko
Xi Xi+\ |> MaxErr;
sprawdzenie, czy liczba iteracji przekracza zadaną maksymalną liczbę ite-
racji Maxlter.
6.7. Wyznaczanie pierwiastków równania
217
Spełnienie pierwszego kryterium oznacza zbieżność metody Newtona, nato-
miast przerwanie obliczeń na skutek spełnienia jednego z dwóch ostatnich wa-
runków sugeruje, że metoda jest rozbieżna lub jej zbieżność jest zbyt wolna.
Przykład 6.8. Zastosujemy metodę Newtona do obliczenia pierwiastka n-tego
stopnia z liczby a. Zatem interesuje nas rozwiązanie następującego równania
x
n - a = 0.
W tym przypadku f(x) = xn a i f'(x) = nxn 1.
otrzymujemy
1
Podstawiając do wzoru (24)
= \(n
i = 0,1,2,...
(25)
gdzie xq > 0. Wzór (25) określa bardzo dobrze zachowującą się numerycznie
metodę znajdowania pierwiastka n-tego stopnia z liczby a (pamiętajmy, że dla n
parzystych a musi być liczbą dodatnią). Przybliżenie początkowe w tym przy-
padku może być dowolną liczbą dodatnią. Za jedno z lepszych przybliżeń przyj-
muje się xq = 1 + (a l)/n. Zachęcamy do wykonania samodzielnego zadania
rachunkowego (por. zad. 6.4 i p. 9.11). ?
Omówimy teraz najważniejsze fragmenty programu ZeraFunkcji, który za
pomocą metody Newtona (24) znajduje pierwiastki równania (23) dla dowolnej
funkcji / w przedziale [a,b].
Uwaga: Tekst kompletnego programu ZeraFunkcji znajduje się na dyskietce w pliku I ; |
ZERAFUNK.PAS umieszczonym w kartotece R0ZDZ6.
Przebieg obliczeń w programie ZeraFunkcji wynika z rozważań przeprowa-
dzonych powyżej i można wyróżnić w nim dwa etapy:
- lokalizację pierwiastków metodą tablicowania (zob. przykład 6.7);
- obliczanie pierwiastków metodą Newtona.
Przedstawiamy poniżej teksty dwóch podprogramów wchodzących w skład
programu ZeraFunkcji, które realizują obliczenia wymienionych etapów - pro-
cedury Tab i funkcji Newton. Pozostałe podprogramy, to funkcje obliczające
wartości funkcji / i jej pochodnej oraz procedury czytania danych i wyprowa-
dzania wyników. Teksty tych ostatnich procedur są podobne do tekstów odpo-
wiednich procedur w programie Testlnterpolacji (zob. p. 6.5).
PROCEDURĘ Tab(a,b,h:REAL;VAR xp,xk:TablicaOn;
VAR lz:INTEGER);
{Procedura wyznacza w przedziale [a,b] podprzedzialy
[xp[i],xk[i]], i=l,2,...,lz o długości h zawierające
218
6. Metody numeryczne
zera rzeczywiste nielokalnej funkcji f, gdzie Iz jest
liczba znalezionych podprzedzialow.}
VAR hl,x,y,yl:REAL;
BEGIN
x:=a;
lz:=0;
WHILE xy:=f(x);
IF y=0.0 THEN BEGIN
xp[lz]:=x; xk[lz]:=x;
x:=x+h
END
ELSE BEGIN
x:=x+h;
yl:=f(x);
IF y*yl<0 THEN BEGIN
xp[lz]:=x-h; xk[lz]:=x
END
END {y<>0.0}
END {WHILE}
END; {Tab}
FUNCTION Newton(xO,Eps,MaxErr:REAL;VAR RozbrBOOLEAN;
VAR MaxIter:INTEGER):REAL;
{Funkcja oblicza w otoczeniu punktu xO z dokładnością Eps
zero funkcji f o pochodnej pf za pomocą metody Newtona (24).
Jeśli proces iteracyjny jest rozbieżny, to parametr Rozb
przyjmuje wartość TRUE. Funkcje f i pf sa nielokalne. War-
tością parametru Maxlter jest liczba wykonanych iteracji.}
VAR xl,x2,eb:REAL;
Iter :INTEGER;
BEGIN
eb:=1.0; Iter:=0; Rozb:=FALSE;
REPEAT
Iter:=Iter+l;
xl:=f(xO); x2:=pf(xO);
IF x2=0.0 THEN Rozb:=TRUE
ELSE BEGIN
6.7. Wyznaczanie pierwiastków równania
219
xl:=x0-xl/x2;
eb:=ABS(xl-xO);
IF (eb>MaxErr) OR (Iter=MaxIter) THEN Rozb:=TRUE
END;
xO:=xl
UNTIL (eb
END; {Newton}
Uwaga: Teksty procedury Tab i funkcji Newton są fragmentami tekstu kompletnego
programu ZeraFunkcji, który znajduje się na dyskietce w pliku ZERAFUNK.PAS umie-
szczonym w kartotece R0ZDZ6.
Przykład 6.9. Jesteśmy przygotowani do wykonania pełnych obliczeń metodą
Newtona. W programie ZeraFunkcji znajdującym się na dyskietce przyjęliśmy,
że funkcja / ma postać f(x) = 3x2e~x 0.3a; 0.2, natomiast końce przedziału,
w którym są poszukiwane jej rzeczywiste zera, są danymi dla programu. Ponadto,
danymi są: h - krok tablicowania funkcji, Eps - dokładność obliczenia zer oraz
MaxErr i Maxlter - parametry, które pozwalają przerwać obliczenia, gdy metoda
Newtona jest rozbieżna.
Dla funkcji f(x) określonej jak wyżej i wartości parametrów a=-l, b=2, h=0.11,
Eps=1.0E-6, MaxErr=10.0 i MaxIter=100 otrzymano następujące wyniki:
Zlokalizowano Iz pierwiastków, gdzie lz=3.
Przedział
Pierwiastek
Iteracje
[-0.340000,-0.230000]
[ 0.430000, 0.540000]
[ 1.310000, 1.420000]
-0.3342425600 4
0.4766029390 3
1.4057332666 3
Zachęcamy do wykonania obliczeń programem ZeraFunkcji dla wybranej
przez siebie funkcji /. Uprzednio w tekście programu należy zmienić opisy funkcji
f i jej pochodnej pf. Proponujemy przeprowadzić obliczenia dla różnych wartości
parametrów, od których zależy przebieg działania metody Newtona.
6.7.3. Równania algebraiczne
Równanie (23), tzn. f(x) = 0, nazywa się równaniem algebraicznym, jeśli
funkcja f(x) jest wielomianem wn(x) w postaci (7) o współczynnikach rzeczy-
wistych. Zgodnie z podstawowym twierdzeniem algebry równanie algebraiczne
stopnia n ma co najwyżej n rzeczywistych pierwiastków. W najprostszym przy-
padku, tzn. gdy równanie ma tylko pojedyncze pierwiastki i nie leżą one zbyt
220
6. Metody numeryczne
blisko siebie, można je znaleźć wykonując następujące obliczenia:
1. Wyznaczyć przedział [a, b] zawierający wszystkie pierwiastki.
2. Dla ustalonego kroku h wyszukać w przedziale [a, b] przez tablicowanie funk-
cji wszystkie podprzedziały, na końcach których wartości funkcji mają prze-
ciwne znaki.
3. W każdym podprzedziale określić przybliżenie początkowe pierwiastka, np.
za pomocą interpolacji liniowej.
4. Dla każdego przybliżenia początkowego wyznaczyć pierwiastek z przyjętą
dokładnością za pomocą metody Newtona.
Z wyjątkiem pierwszego kroku tej metody pozostałe kroki potrafimy już u-
zupełnić odpowiednimi algorytmami. Musimy więc podać sposób wyznaczania
przedziału [a, b] zawierającego wszystkie pierwiastki rzeczywiste wielomianu. W
tym celu skorzystamy z następującego twierdzenia pochodzącego od Lagrange'a:
Twierdzenie 6.2 (Lagrange). Załóżmy, że ao > 0 i a^ jest pierwszym ujem-
nym współczynnikiem wielomianu (7), a B jest największym z modułów ujemnych
współczynników tego wielomianu. Wówczas
jest liczbą większą od wszystkich dodatnich pierwiastków wielomianu (7).
Z drugiej strony, aby wyznaczyć wartość a (lewego końca przedziału zawie-l
rającego pierwiastki), możemy zastosować to samo twierdzenie do wielomianu!
vn(x) = wn(-x).
Na zakończenie naszych rozważań poświęconych metodom numerycznym oma-J
wiamy program ZeraWielomianow wyznaczający pierwiastki równania algebra
icznego wyżej opisaną metodą.
I ; j Uwaga: Tekst kompletnego programu ZeraWielomianow znajduje się na dyskietce wj
pliku ZERAWIEL.PAS umieszczonym w kartotece RDZDZ6.
Obliczenia programem ZeraWielomianow przebiegają podobnie jak progra-1
mem ZeraFunkcji. Zasadnicze różnice są następujące:
1. Wykorzystując twierdzenie Lagrange'a można wyznaczyć przedział zawie-l
rający wszystkie zera rzeczywiste wielomianu. Wykonuje to procedura]
Przedział, której tekst zamieszczamy poniżej.
2. Odpowiednikami procedury Tab i funkcji Newton z programu ZeraFunkcji 1
są w programie ZeraWielomianow procedura TabWiel i funkcja NewtonWiel,
w których wartości wielomianu (czyli funkcji, której zer szukamy) są obli-
czane za pomocą funkcji Homer zdefiniowanej w punkcie 6.3.
6.7. Wyznaczanie pierwiastków równania
221
PROCEDURĘ Przedzial(n:INTEGER;a:TablicaOn; VAR ax,bx:REAL);
{Dla wielomianu stopnia n o współczynnikach a [i], i=0,...,n,
procedura wyznacza przedział [ax,bx] zawierający wszystkie
jego zera rzeczywiste.}
VAR i:INTEGER;
b:TablicaOn;
FUNCTION LimSup(n:INTEGER;a:TablicaDn):REAL;
VAR i,k :INTEGER;
g,r,ri,r2:REAL;
BEGIN
r:=a[0]; i:=0; k:=0;
REPEAT
i:=i+l; rl:=a[i];
IF r*rl<0 THEN k:=i
UNTIL (k>0) OR (i=n);
IF k=0 THEN LimSup:=0
ELSE BEGIN
g:=0;
FOR i:=l TO n DO BEGIN
rl:=a[i]; r2:=ABS(rl);
IF (r*rl<0) AND (g
LimSup:=1+EXP(LN(ABS(g/r))/k)
END {k<>}
END; {LimSup}
BEGIN
bx:=LimSup(n,a);
b:=a;
IF ODD(n) THEN
FOR i:=0 TO (n+1) DIV 2 DO
b[2*i] :=-a[2*i]
ELSE
FOR i:=l TO n DIV 2 DO
b[2*i-l]:=-a[2*i-l];
ax:=-LiraSup(n,b)
END; {Przedział}
Uwaga: Tekst procedury Przedział jest fragmentem programu ZeraWielomianow,
który znajduje się na dyskietce w pliku ZERAWIEL.PAS umieszczonym w kartotece
R0ZDZ6.
222
6. Metody numeryczne
Przykład 6.10. Programu ZeraWielomianow użyto do znalezienia miejsc zero-
wych następującego wielomianu
x7 - 3x6 -
12x4 - x3 + 3x2
- 12.
Przyjęto krok tablicowania h=0.15, dokładność obliczania zer Eps=lE-8 oraz
MaxIter=10 i MaxErr=l. Niżej prezentujemy otrzymane wyniki.
Przedział zawierający zera wielomianu:
[-4.46410E+00, 1.30000E+01]
Wielomian ma co najmniej Iz zer rzeczywistych, gdzie lz=5.
Przedział Pierwiastek Iteracje
[-2.064102
,-1.914102]
-2.000000000
4
[-1.014102
,-0.864102]
-1.000000000
4
[ 0.935898
, 1.085898]
1.000000000
3
[ 1.985898
, 2.135898]
2.000000000
4
[ 2.885898
, 3.035898]
3.000000000
4
Zadania
6.1. Działania arytmetyczne na liczbach o i-cyfrowej mantysie są wykonywane
we współczesnych komputerach z dokładnością do 2t cyfr, a otrzymywany wy-
nik zaokrągla się do t cyfr. Na przykład dodanie liczb a = 0.1007 ? 105 oraz
b = -0.9232 103 dla t = 4 przebiega następująco:
- sprowadzanie liczb do postaci o jednakowych cechach i wykonanie dodawa-
nia:
r = 0.1007 105 + (-0.009232) 105 = 0.091468 105;
- normalizacja mantysy, czyli sprowadzanie mantysy do przedziału (4) oraz
zaokrąglenie jej do 4 cyfr
r = 0.91468 105, fi(a + b) = 0.9147 105.
a. Sprawdź, że dla dodawania zmiennopozycyjnego nie zachodzi na ogół prawo
łączności. W tym celu oblicz wielkości
5i = fl(a + fl(6 + c)) i S2 = fł(fł(a + b) + c)
i
I
Zadania
223
w arytmetyce 7-cyfrowej dla liczb a = 0.1234567 10, b = 0.4711325 104 oraz
c=-b.
b. Przy obliczaniu H(a + b) w części a zadania, ze względu na konieczność
denormalizacji mantysy liczby a (w czasie sprowadzania liczb do jednakowych
cech), wystąpiła utrata cyfr po zaokrągleniu. Stracone cyfry można odzyskać
obliczając
P = fl(fl(6-fi(a + 6)) + a).
Oblicz P w arytmetyce 7-cyfrowej dla a i b z części a zadania.
c. Poprawkę P można wykorzystać. Oblicz S = fl(P + S2) z dokładnością
do siedmiu cyfr i porównaj wynik z wartością S\, gdzie S\ i S2 są wielkościami
obliczonymi w części a.
6.2. Sprawdź prawdziwość równości (10) i (11).
6.3. Wykaż prawdziwość zależności rekurencyjnej (16).
6.4. Napisz program, który jest realizacją algorytmu iteracyjnego zapisanego wzo-
rem (25) i nie korzysta z funkcji Newton, opisanej w p. 6.7. Umieść w programie
liczenie liczby iteracji metody. Wykonaj obliczenia dla różnych liczb podpier-
wiastkowych, różnych przybliżeń początkowych i różnych dokładności. Porównaj
liczby wykonanych iteracji.
6.5. Bardzo ważną rolę w wielu działach metod numerycznych odgrywają wie-
lomiany Czebyszewa, które najczęściej są definiowane rekurencyjnie w nastę-
pujący sposób:
T0(x) = 1, Ti(x) = x,
Tn(x) = 2zTn_i(z) - Tn^2(x), n = 2, 3,...
a. Sporządź opis niestandardowej funkcji rekurencyjnej o nagłówku
FUNCTION WielCzebRek(n:INTEGER;x:REAL):REAL
której wartością jest Tn(x).
b. Nie korzystając z pomocy komputera oblicz wartość wielomianu Czeby-
szewa Tq(1.5), stosując powyższe wzory rekurencyjne. Zauważ przy tym, że nie-
które wartości wielomianów niższych stopni są liczone wielokrotnie.
c. Nieefektywność z części b zadania można usunąć zamieniając rekurencyjny
sposób obliczania wartości wielomianów Czebyszewa na iteracyjny. Sporządź opis
niestandardowej funkcji o nagłówku
FUNCTION WielCzebIter(n:INTEGER;x:REAL):REAL
której wartością jest Tn(x) liczona iteracyjnie (por. zad. 4.4 i 4.5).
224
6.6. Opracuj program obliczania pierwiastków równania kwadratowego według
wzorów (13). Wykonaj obliczenia i porównaj otrzymane rozwiązania z wynikami
procedury Rownanie2. Przyjmij dla przykładu p = 1000.00001 i q = 0.01.
6.7. Rozwiąż w arytmetyce 3-cyfrowej następujący układ równań
0.300s + 0.212?/ = 0.890
O.lOOa; - 0.100y = -0.130
Wyznacz błędy względne obliczonych wartości niewiadomych, jeśli dokładne war-
tości są równe a; = 1.2 i y = 2.5. Czy powyższy układ jest zadaniem dobrze
uwarunkowanym? Odpowiedź uzasadnij.
6.8. Wzorując się na programie Testlnterpolacji, opracuj program wyzna-
czający dla funkcji f(x) w przedziale [a, b] wielomiany interpolacyjne wn(x) stopni
n= 1,2,... oraz obliczający dla każdego n odległość p(f,wn). Za kryterium
zakończenia obliczeń przyjmij spełnienie jednego z warunków: p(f, wn) < e
lub n > Maxn, gdzie e jest rzędem dokładności przybliżenia funkcji / przez
wn, a Maxn jest górnym ograniczeniem na stopień wielomianu interpolacyj-
nego. Wykonaj obliczenia dla następujących danych: f(x) = exp(x2), [a,b] =
[-0.25,0.25], Maxn = 10 i Eps = 1E-9.
6.9. Opracuj program porównujący skuteczność złożonych kwadratur trapezów
i Simpsona. Program powinien powtarzać obliczenia całki obiema metodami,
dzieląc przedział całkowania na m = 2l części, dla i = 1, 2,..., n.
6.10. Oblicz pole elipsy x'2/4 + y2/9 = 1 jako wartość odpowiedniej całki.
6.11. Dla dowolnej liczby a > 1 prawdziwy jest wzór
1 f \ F dx
ln(a) = / .
J\ x
Stosując wzór Simpsona dla różnych liczb podziałów przedziału całkowania, oblicz
wartości ln(2), ln(2.5), In(3). Porównaj otrzymane przybliżenia z wartościami lo-
garytmów wziętymi z tablic lub otrzymanymi przez odwołanie się do standardowej
funkcji LN.
6.12. Oblicz pole ograniczone krzywą y = x3 + 3x 14, osią Ox i prostą
5x + Ay = 20.
Wskazówka: Wyznacz punkty przecięcia się krzywych i skorzystaj z całkowa-
nia.
6.13. Za pomocą programu ZeraWielomianow znajdź wszystkie pierwiastki rze-
czywiste następującego wielomianu:
w5(x) = x5 -
4x - 20.
7. LICZYĆ SZYBCIEJ
ALGORYTMÓW
EFEKTYWNOŚĆ
7.1. Złożoność obliczeniowa
Opisywane przez nas algorytmy zapewniają poprawne rozwiązywanie postawio-
nych zadań. Staramy się także by były one jak najprostsze, a realizujące je
programy działały jak najefektywniej, czyli także jak najszybciej.
W rozdziale 4 rozważaliśmy zadanie polegające na wyznaczeniu dla dwóch
danych liczb naturalnych a i b trzeciej liczby naturalnej z, oznaczonej przez
NWD(a, b), będącej największym wspólnym dzielnikiem liczb a i b. Omówiliśmy
tam naiwny algorytm wyznaczania liczby z oraz algorytm pochodzący od Eukli-
desa i przedstawiliśmy realizację tego drugiego w języku Pascal. Uzasadniliśmy,
że oba algorytmy działają poprawnie, tzn. dla każdych dwóch liczb naturalnych a
i b zatrzymują się po skończonej liczbie kroków, a końcowa wartość zmiennej z jest
równa NWD(a, b). Postawiliśmy sobie także pytanie, jaka jest zależność między
liczbą kroków a wartościami danych a i 6 w tych algorytmach. Algorytm naiwny
może w pewnych przypadkach wykonywać tyle kroków, ile wynosi mniejsza z liczb
a i b, dla algorytmu Euklidesa zaś nie podaliśmy żadnej zależności, gdyż nie jest
to takie łatwe. Proponujemy sprawdzić samodzielnie, dla jakich danych algorytm
Euklidesa wykonuje dużą liczbę kroków a dla jakich małą (por. zad. 7.1).
W następnych punktach przeanalizujemy kilka dalszych prostych zadań, al-
gorytmów i programów, by zilustrować podstawowe pojęcia związane ze sposo-
bami oceny efektywności algorytmów i programów. Za miarę dobroci algorytmu
przyjmujemy liczbę wykonywanych w nim elementarnych operacji takich, jak do-
dawanie czy porównywanie (tj. sprawdzanie prawdziwości relacji <). W przy-
padku programu komputerowego efektywność jego działania można także oce-
niać na podstawie czasu pracy. Obie wielkości, liczbę elementarnych operacji
algorytmu i czas działania programu nazywamy miarą złożoności lub po pro-
stu złożonością obliczeniową algorytmu (lub programu). Bardziej potocznie
złożoność jest nazywana pracochłonnością. Złożonością algorytmu posługujemy
15 Elementy informatyki
226
7. Efektywność algorytmów
się porównując różne metody rozwiązywania tego samego zadania i często jest to
najważniejsze kryterium wyboru algorytmu.
Za uzasadnienie ważności naszych rozważań w tym rozdziale można przyjąć
następujące dwa fakty:
- spośród wielu algorytmów rozwiązujących dany problem powinniśmy umieć
wybrać ten najlepszy, czyli na przykład najszybszy,
- posiadanie nawet wyszukanego algorytmu rozwiązywania nie powinno wy-
kluczać poszukiwań jeszcze lepszych metod rozwiązywania.
Chociaż są budowane coraz szybsze komputery, to jednak istnieją problemy
(np. należące do klasy problemów NP-zupełnych), których dla dużych roz-
miarów danych nie można rozwiązać za pomocą żadnego z istniejących kompu-
terów i są małe szansę, że sytuacja ta szybko ulegnie zmianie (por. zad. 7.4). Cała
więc nadzieja w coraz efektywniejszych algorytmach.
?
7.2. Złożoność algorytmu a czas działania programu
Zajmiemy się tutaj analizą złożoności obliczeń wykonywanych za pomocą pro-
gramu CzasSumowania, którego główną składową jest opisana w nim funkcja
Suma. Wartością tej funkcji jest YL'iLixi' ^zn- suma rn kolejnych elementów
ciągu x poczynając od x\. Głównym zadaniem tego programu jest wyznaczanie
czasu obliczania wartości funkcji Suma dla różnych długości sumowanego ciągu.
W tym celu stosujemy procedurę standardową GETTIME oraz napisaną przez nas
funkcję niestandardową PrintTime. Pierwsza z nich ma cztery parametry: g,
m, s i r typu WORD (oznaczające odpowiednio godziny, minuty, sekundy i setne
części sekund) i podaje aktualny czas, a wartością funkcji PrintTime jest różnica
między dwoma punktami w czasie (gl,ml,sl,rl) i (g2,m2,s2,r2), wyrażona
w sekundach. Zdefiniowanie funkcji PrintTime pozostawiamy do samodzielnego
wykonania (zob. rozwiązanie zad. 7.3 w EI-II).
{$N->
PROGRAM CzasSumowania;
USES CRT.DOS;
COWST MaxM=1000;
TYPE TablicaR=ARRAY[l..MaxM] OF REAL;
VAR j,m :INTEGER;
gl.ml.sl.rl,
g2,m2,s2,r2 :W0RD;
r :REAL;
a :TablicaR;
FUNCTION Suma(m:INTEGER;x:TablicaR):REAL;
7.2. Złożoność a czas działania
227
VAR i:INTEGER;
s:REAL;
BEGIN
{1.} s:=x[l];
FOR i:=2 TO m DO
{2.} s:=s+x[i] ;
{3.} Suma:=s
EMD; {Suma}
{Pominięty został opis funkcji niestandardowej PrintTime,
zob. rozw. zad. 7.3.}
BEGIN
CLRSCR;
REPEAT
WRITE('Podaj liczbę sumowanych elementów m (m=<',MaxM,') = ');
READLN(m);
IF m>MaxM THEN WRITELN('Musi byc m<',MaxM)
UNTIL m<=MaxM;
FOR j:=l TO m DO a[j]:=RAND0M;
GETTIME(gl5ml,sl,rl);
r:=Suma(m,a);
GETTIME(g2,m2,s2,r2);
WRITELNCsuma ' ,m,' liczb =' ,r,';');
WRITELNCczas sumowania = '.PrintTime,' sek');
READLN;
WRITECNacisnij dowolny klawisz');
REPEAT UNTIL KEYPRESSED
END. -[CzasSumowania}
Uwaga: Tekst kompletnego programu CzasSumowania znajduje się na dyskietce w pliku
CZASSUMA.PAS umieszczonym w kartotece R0ZDZ7.
Ten sam program może być użyty do obliczenia wartości sumy zarówno dwóch
jak i tysiąca liczb, które są generowane losowo za pomocą funkcji standardowej
RANDOM. Zatem długość programu, jakbyśmy jej nie mierzyli (np. liczbą wierszy),
nie może reprezentować złożoności wykonywanych za jego pomocą obliczeń, gdyż
dodanie dwóch liczb będzie trwało oczywiście krócej niż dodanie tysiąca liczb.
Określenie złożoności algorytmu zrealizowanego w powyższym programie jest
dość proste. Liczba elementarnych operacji wykonywanych w funkcji Suma zależy
wprost proporcjonalnie od liczby składników sumy, tzn. im więcej liczb mamy do
dodania, tym dłużej to potrwa. Możemy nawet wyznaczyć dokładną liczbę wyko-
nywanych działań. W przypadku liczenia sumy najistotniejszym działaniem jest
dodawanie. Funkcja Suma wykonuje ml dodawań w pętli FOR, a więc dokładnie
228
7. Efektywność algorytmów
tyle, ile znaków dodawania jest w sumie x\ + 22 + ? ? + xm. Ponadto w trakcie
obliczania wartości funkcji Suma powyższym programem, poza dodawaniem kom-
puter wykonuje wiele innych operacji o różnych jednostkowych czasach działania.
Wszystkie operacje można jednak podzielić na dwie zasadnicze grupy:
- operacje, których liczba zależy od m (jak np. przypisania w instrukcji FOR
w wierszu nr 2,
- operacje, których liczba nie zależy od liczby dodawanych elementów (jak
np. przypisania w wierszach nr 1 i 3).
Czas działania funkcji Suma możemy więc wyrazić w postaci zależności:
t(m) = Am + B,
(1)
gdzie we współczynniku A zostały uwzględnione czasy wykonania wszystkich ope-
racji z pierwszej grupy, a we współczynniku B - operacji z drugiej grupy. Wartości
tych współczynników można wyznaczyć na podstawie kilku przykładowych wy-
konań programu CzasSumowania dla różnych wartości m. W tym celu, w układzie
XT(12 MHz)
3000 5000
10000
15000
20000
30000
Rys. 7.1. Wykresy funkcji t{m) otrzymane dla komputerów: IBM PC/XT i AT
współrzędnych o osiach odpowiadających m i t(m), nanosimy czasy obliczeń t(m)
dla kilku wartości m i rysujemy prostą przechodzącą możliwie blisko tych punk-
tów. Zauważmy, że to, iż sumowane liczby są generowane losowo, nie ma wpływu
na wartości współczynników A i B , gdyż czas dodawania w komputerze dwóch
liczb ustalonego typu (INTEGER lub REAL) jest stały i nie zależy od wartości
7.3. Dwa algorytmy optymalne
229
składników. Wartości współczynników we wzorze (1) zależą więc jedynie od ro-
dzaju komputera, na którym są wykonywane obliczenia. Ilustrują to wykresy
przedstawione na rys. 7.1. Zachęcamy także do wykonania własnych ekspery-
mentów (por. zad. 7.5).
Znajomość złożoności programu w postaci zależności czasu działania od dłu-
gości danych (czyli od ich liczby) jest bardzo pożyteczna. Po pierwsze, we współ-
czynnikach są uwzględnione nie tylko liczby poszczególnych operacji, ale także
ich rzeczywiste czasy wykonywania. Po drugie, wzór (1) może być użyty do
wyznaczenia przybliżonego czasu obliczania wartości funkcji Suma dla dowolnej
liczby składników m. Na przykład, czas dodania 15 tys. liczb na komputerze
IBM PC/XT odczytany z wykresu na rys. 7.1 wynosi 12.56 s, a w rzeczywistości
wyniósł 12.63 s1.
7.3. Dwa algorytmy optymalne
Scalanie ciągów
Powróćmy do zadania, które pojawiło się w rozdz. 5 przy łączeniu dwóch plików.
Procedura Lacz (por. przykład 5.5) scala ze sobą dwa pliki rekordów, w których
są zapamiętane dane o książkach. Ponadto założyliśmy tam, że rekordy w pli-
kach danych i w tworzonym pliku są uporządkowane alfabetycznie ze względu na
nazwisko i imię autora oraz na tytuły jego książek. Uprościmy tutaj to zada-
nie i zajmiemy się łączeniem dwóch ciągów złożonych z liczb i uporządkowanych
zgodnie z relacją < w jeden ciąg uporządkowany tą samą relacją.
Algorytm zaprogramowany w procedurze Lacz polega na przeglądaniu obu
plików od początku i przenoszeniu do tworzonego pliku mniejszego z dwóch
bieżących elementów. Podamy teraz ten algorytm jeszcze raz (w procedurze
Scal) w wersji dostosowanej do dalszych zastosowań omawianych w p. 7.5. Róż-
nica polega na tym, że rezygnujemy tutaj z użycia wartownika w ciągu liczb dla
zaznaczenia końca danych. Algorytmy stają się przez to bardziej efektywne, cho-
ciaż ich opis jest mniej jednorodny. Zakładamy, że uporządkowane podciągi, które
mają być scalone, są umieszczone w jednej tablicy x, na miejscach od Początek
do Granica1 i od Granica do Koniec, i po scaleniu w jeden ciąg mają być
umieszczone na tym samym miejscu, czyli w tablicy x na miejscach od Początek
do Koniec.
Zauważmy, że ciąg powstający w trakcie scalania dwóch ciągów nie może być
bezpośrednio umieszczany na miejscu któregokolwiek ze scalanych ciągów, nawet
jeśli oba ciągi są dane w jednej tablicy tak, jak w procedurze Scal. (Podobna
1 Zaproponuj modyfikację programu CzasSumowania tak, aby można było wyznaczać nim czas
sumowania 100 tys. liczb typu REAL.
230
7. Efektywność algorytmów
uwaga odnosi się także do scalania plików.) Dlatego wynik scalania musi być
zapisywany w dodatkowej tablicy. W naszym przypadku jest nią tablica z. Po
scaleniu ciągów, otrzymany ciąg jest z powrotem kopiowany do tablicy x, w której
dane były ciągi do scalenia.
PROCEDURĘ Scal(Poczatek,Granica,Koniec:INTEGER;
VAR x:TablicaR);
VAR i,j,l:INTEGER;
z :TablicaR;
BEGIN
i:=Poczatek; j:=Granica; l:=Poczatek;
WHILE (KGranica) AND (j<=Koniec) DO BEGIN
IF x[i]<=x[j] THEN BEGIN
z[l] :=x[i] ; i:=i+l END
ELSE BEGIN z [1]:=x[j]; j:=j + l END;
END;
{dołączanie końcówki pierwszego podciągu}
WHILE i
{dołączanie końcówki drugiego podciągu}
WHILE j<=Koniec DO BEGIN
END;
{kopiowanie wyniku z powrotem do tablicy x}
FOR i:=Poczatek TO Koniec DO
END; {Scal}
Uwaga: Tekst procedury Scal jest fragmentem tekstu procedury ScalSort znajdującej
się na dyskietce w pliku SCALSORT.PAS umieszczonym w kartotece R0ZDZ7.
Aby uzasadnienie poprawność działania procedury Scal zauważmy, że wszy-
stkie elementy obu podciągów są przeglądane i zapisywane w odpowiedniej ko-
lejności w tablicy z, a później z powrotem w tablicy x. Zastanówmy się jednak
głębiej, co można powiedzieć o efektywności użytej metody. Uzasadnimy twier-
dzenie, że w pewnym sensie jest to najszybsza metoda scalania dwóch ciągów.
Wyznaczmy najpierw, ile wynosi liczba działań wykonywanych w procedurze
Scal. W każdej iteracji każdej z trzech pętli WHILE tablica z jest powiększana
7.3. Dwa algorytmy optymalne
231
i
dokładnie o jeden element. Zatem liczba przypisań elementom tablicy z ele-
mentów scalanych podciągów wynosi dokładnie tyle, ile elementów po wykona-
niu tej procedury ma tablica z, a później x. Zauważmy, że jakikolwiek algorytm
scalający musi wykonać przynajmniej tyle samo takich przypisań, gdyż podciągi
scalane muszą być przeniesione do tworzonego ciągu.
Policzmy teraz, ile porównań (tzn. sprawdzeń nierówności < lub <) między
porządkowanymi elementami wykonuje procedura Scal. Liczba porównań jest
bowiem naj powszechniej stosowaną miarą służącą do oceny efektywności algo-
rytmów porządkujących. Tego typu nierówności są sprawdzane tylko w pierwszej
pętli WHILE. Pętla ta zaś jest wykonywana tak długo, jak długo każdy ze scalanych
podciągów ma przynajmniej jeden element. W najmniej korzystnym przypadku,
po zakończeniu wykonywania pierwszej pętli WHILE, z obu podciągów pozostaje
w którymś z nich dokładnie jeden element, który jest dołączany w jednej z dwóch
ostatnich pętli WHILE. Wynika stąd, że procedura Scal wykonuje co najwyżej
(KoniecPoczatek+1) 1 = KoniecPoczątek porównań.
Zastanówmy się teraz, czemu jest równa liczba porównań niezbędna do sca-
lenia dwóch podciągów. Ostatnim elementem w scalonym ciągu jest element,
który pozostanie z obu ciągów na końcu. Z kolei, aby ustalić przedostatni element
w scalonym ciągu (czyli element o wskaźniku Koniec 1), należy wykonać przy-
najmniej (Koniec1)Poczatek+1 czyli KoniecPoczątek porównań. Każdy
bowiem z elementów ciągu o wskaźniku między Początek i Koniec 1 musi być
porównany przynajmniej z jednym elementem, by znaleźć dla niego odpowiednie
miejsce w uporządkowanym ciągu.
Wykazaliśmy, że z jednej strony liczba porównań (a także przypisań) wyko-
nywanych w procedurze Scal wynosi co najwyżej KoniecPoczątek, a z drugiej
- że mniejsza być nie może. W najgorszym przypadku jest więc wykonywanych
dokładnie tyle porównań, ile wynosi najmniejsza liczba porównań potrzebnych
do scalenia dwóch uporządkowanych ciągów. Algorytm o takiej własności funkcji
złożoności nazywamy optymalnym.
Zapamiętajmy z dyskusji powyżej, że scalenie dwóch uporządkowanych cią-
gów o łącznej długości m wymaga wykonania m 1 porównań w najmniej ko-
rzystnym przypadku, czyli o jeden mniej od całkowitej liczby elementów w obu
ciągach.
Wyznaczanie minimum
Omówimy teraz zadanie, które jest jeszcze prostsze niż scalanie uporządkowanych
ciągów i wykażemy, że algorytm stosowany najczęściej do jego rozwiązania jest
najlepszą możliwą metodą, tzn. jest optymalny. Nasze zadanie polega teraz na
znalezieniu minimum, czyli najmniejszego elementu wśród ciągu danych. For-
232
7. Efektywność algorytmów
malnie zapisujemy
min = minimum{xi, ?2, , xm}.
Nie ma chyba nikogo, kto nie wiedziałby, jak wyznaczyć min i chyba wszyscy
mamy na myśli ten sam algorytm:
1. przyjmij za min pierwszy element ciągu;
2. dla i = 2,3,... ,m sprawdź czy Xi nie jest mniejsze od min; jeśli tak, to
podstaw Xi pod min.
Zapiszmy ten algorytm w postaci niestandardowej funkcji Pascala, której
wartością jest najmniejszy element w ciągu m liczb danych w tablicy x[l. .m],
gdzie m
VAR i:INTEGER;
y:REAL;
BEGIN
y:=x[l];
FOR i:=2 TO m DO
IF x[i]
END; {Min}
I , I Uwaga: Tekst funkcji Min znajduje się na dyskietce w pliku MIN.PAS umieszczonym w
kartotece R0ZDZ7.
Podstawową operacją w treści tej funkcji jest porównanie dwóch elementów
z tablicy x wykonywane w pętli FOR (jedną z liczb jest x [i], a druga jest ukryta
pod zmienną y), która przebiega po wartościach wskaźnika i od 2 do m. Za-
tem dla ciągu złożonego z m elementów funkcja Min wykonuje m 1 porównań.
Pokażemy teraz w sposób dość ścisły, że nie można tego zadania wykonać szybciej,
tzn. jakikolwiek algorytm wyznaczający najmniejszą spośród m liczb wykonuje
przynajmniej m 1 porównań między tymi liczbami.
Poczyńmy najpierw pewne założenia. Po pierwsze, naszą uwagę skupimy na
algorytmach, które - by znaleźć min - wykonują porównania, ale tylko między
elementami ciągu danych, a więc nie sprawdzają na przykład czy x\ 2 > 4^3. Po
drugie, za miarę złożoności algorytmu przyjmujemy tylko liczbę wykonywanych
porównań między elementami ciągu danych. Uściślijmy więc jeszcze nasz problem
algorytmiczny. Danymi są: długość ciągu elementów m oraz liczby tworzące ten
ciąg xi, X2, ? ? ?, xm. Należy znaleźć najmniejszy co do wartości element tego ciągu.
Na początku, jeszcze przed wykonaniem jakichkolwiek obliczeń, każda z m
danych liczb X{ może potencjalnie być najmniejszą w tym ciągu, a jako wynik
powinniśmy otrzymać dokładnie jedną liczbę będącą najmniejszą w tym ciągu.
Zatem nasze zadanie polega na przeprowadzeniu zbioru m elementowego X =
7.3. Dwa algorytmy optymalne
233
{xi, x%,..., xm\ w zbiór jednoelementowy utworzony z min tego zbioru. Dopu-
szczamy, że X może być zbiorem z powtórzeniami, jeśli ciąg x zawiera elementy
o takich samych wartościach. Ponadto przyjmujemy, że jeśli X zawiera wiele ele-
mentów minimalnych, to min jest dowolnym z nich. Korzystając z tych uściśleń
możemy teraz zapisać nasz problem w następującej postaci:
przeprowadzić parę zbiorów (X, 0) w parę (min, X {min}).
Tej transformacji pary zbiorów odpowiada następująca zmiana ich liczebności:
Możemy teraz już dość dokładnie określić możliwe kroki jakiegokolwiek al-
gorytmu znajdującego min, który realizuje powyższą transformację. Algorytm
taki powinien przeprowadzać parę zbiorów (X, Y) o początkowych liczebnościach
(m, 0) w parę o liczebnościach (l,m 1) stosując jedynie porównania między
elementami tych zbiorów. Określmy więc, jaki wpływ na parę zbiorów (X,Y)
o liczebnościach (k,l), gdzie k + I = m, ma wykonanie jednego porównania
dwóch elementów należących do sumy zbiorów X i Y. Możliwe są cztery ro-
dzaje porównań:
a <
Ca'
dla
a,
a1
E
a <
C b
dla
a
X
i 6
E
b<
' a
dla
a
e
X
ib
E
y,
b<
:b'
dla
b.
b'
E
Y.
W pierwszym przypadku, jeśli nierówność jest prawdziwa, to możemy prze-
nieść a1 z X do Y, a jeśli nie (tzn. a > a'), to możemy przenieść a z X do Y.
Zatem po wykonaniu porównania pierwszego rodzaju, zmniejsza się o jeden liczba
elementów w zbiorze X, a zwiększa w zbiorze Y. Możemy więc scharakteryzować
to porównanie przejściem (k,l) => (k 1,1 + 1).
W drugim przypadku, jeśli zachodzi a < b, to element a musi nadal pozostać
w zbiorze X. W przeciwnym zaś razie, tzn. gdy a > b, rozumujemy w zależności
od tego czy jest to nierówność słaba, czy ostra. Jeśli a > 6, to możemy przenieść
a z X do Y, gdyż dla elementu b istnieje element a" w X spełniający a" < b,
a zatem mamy a" < b < a, czyli także a" < a. Jeśli natomiast a = b, to nie
mamy dość informacji, by zadecydować o tym, co zrobić z o bez porównania go
z innymi elementami w zbiorze X (dokładniej, jeśli a jest jedynym najmniejszym
elementem w X, to musi tam pozostać, a w przeciwnym razie można przenieść a
do Y). Zatem porównania drugiego rodzaju można scharakteryzowaćprzejściem
(k,ł) =>(k,l) lub (k-1,1 + 1).
Podobnie można opisać trzeci rodzaj porównania. W ostatnim zaś przypadku
wynik porównania nie ma żadnego wpływu na parę zbiorów (X, Y). Analizę wszy-
stkich rodzajów porównań możemy więc podsumować następującym wykazem
odpowiadających im przejść:
234
7. Efektywność algorytmów
a
<
a':
(k,
l) =
^(Jfe-
l.Z + 1),
a
<
b:
(k,
1) =
>{k,l)
b
<
a :
(k,
Z) =
>(k,l)
lub (jfe- 1,/
1),
Wynika stąd, że największe zmiany liczebności zbiorów X i Y w jednym kroku
zachodzą podczas wykonywania porównań pierwszego rodzaju i - by przejść od
stanu (m,0) do stanu (l,m 1) - takich kroków należy wykonać m 1. Wyka-
zaliśmy więc prawdziwość następującego twierdzenia:
Twierdzenie 7.1. Wyznaczenie najmniejszej spośród m liczb wymaga wykona- J
nia co najmniej m 1 porównań między tymi liczbami.
Ponieważ w funkcji Min jest wykonywanych dokładnie m l porównań między
elementami ciągu x, zatem jest ona realizacją optymalnego algorytmu wyznacza-
nia min.
7.4. Porządkowanie ciągów
Porządkowanie, zwane także sortowaniem, jest jednym z najczęściej wy-
konywanych zadań przez komputery. Uporządkowanie zbioru danych ułatwia
korzystanie z niego, na przykład łatwiej można znaleźć w nim określony ele-
ment lub wstawić nowy element z zachowaniem porządku. W komputerach
porządkowane są liczby i słowa (a ogólniej napisy, czyli ciągi znaków). W pierw-
szym przypadku porządkowanie polega na znalezieniu kolejności liczb zgodnej
na przykład z relacją <, a w przypadku porządkowania nazw - na ustawianiu
ich w porządku słownikowym (lub alfabetycznym) zwanym także leksy-
kograficznym. Dla przykładu, uporządkowaniem ciągu liczb (2',1,2",10,3,0)
jest ciąg (-1,0,2',2",3,10) a także ciąg (-1,0,2",2',3,10) (primem oznaczyliśmy
pierwsze pojawienie się w ciągu liczby 2, a bisem - drugie; dopuszczamy, że
porządkowane ciągi mogą zawierać elementy o tych samych wartościach). Na-
tomiast nazwy (kotara,tara,kotka,ara,kotek) występują w słowniku w kolejności
(ara, kotara, kotek, kotka, tara).
Różnica między sposobami porządkowania nazw, a porządkowaniem liczb wy-
nika przede wszystkim z różnic w sposobach pamiętania porządkowanych elemen-
tów. Pojedyncze znaki nazw mogą być (i najczęściej są) pamiętane w oddzielnych
bajtach - mamy wtedy do nich bezpośredni dostęp i możemy z nich korzystać. Na-
tomiast kolejne cyfry dziesiętne liczb (zwłaszcza typu REAL) są trudniej dostępne,
gdyż w komputerze liczby są najczęściej reprezentowane przez swoje wartości,
często przybliżone, a nie jako ciągi osobno pamiętanych cyfr.
Porównywanie nazw może być sprowadzone do porównywania ich liczbowych
kodów. Korzystaliśmy z tego w rozdz. 5 porównując jako liczby klucze rekordów
7.4. Porządkowanie ciągów
235
utworzone ze zlepienia nazwiska i imienia autora oraz tytułu książki. Dalej główną
uwagę skupimy przede wszystkim na porządkowaniu liczb, a metoda koszykowa
stosowana do porządkowania nazw znak po znaku w swojej najprostszej postaci
jest opisana w zadaniu 7.13.
Aby uściślić zadanie porządkowania liczb, wprowadźmy następujące oznacze-
nia, ułatwiające także zapis algorytmów. Dany jest ciąg niekoniecznie różnych
m liczb x = (xi,X2, ? ? ? ,xm) i należy znaleźć ich kolejność od najmniejszej do
największej. Na przykład, dla ciągu
, ?2, X3, X4,
= (2',-----1,2", 10, 3, 0),
jedno z szukanych uporządkowań ma postać
(x2, x$, xi,x3, z5, x4) = (-1, 0, 2', 2", 3,10).
W ogólnym przypadku uporządkowany ciąg
jest permutacja ciągu danych, tzn. jest pewnym przestawieniem elementów
ciągu z, zatem ciąg wskaźników (i\,i2, ? , im) jest permutacja ciągu (1,2,..., m).
W naszym przykładzie mamy
(*1,*2,3,*4,5,*6) = (2,6,1,3,5,4).
Zauważmy, że rozwiązanie zadania porządkowania (tzn. kolejność elementów
zgodna z relacją <) może być jednoznacznie wyznaczone przez podanie permu-
tacji wskaźników określającej ten porządek.
Przedstawione dalej algorytmy porządkujące wyznaczają jako rozwiązanie
właściwą permutację ciągu danych. Dla wielu zastosowań jest to duże uproszcze-
nie rzeczywistego problemu. Najczęściej bowiem pojawia się zadanie uporządko-
wania pewnych elementów według jednej z ich cech, zwanej kluczem (por. p. 5.3).
Elementy mogą mieć bardzo rozbudowaną strukturę i stanowić tylko niewielką
część dużej bazy danych. Dla przykładu, na podstawie bazy danych osobowych
przedsiębiorstwa możemy chcieć wydrukować listę pracownic w kolejności długości
ich stażu pracy, od najkrócej pracujących. W takich przypadkach przestawianie
całych elementów (czyli całego rekordu danych o pracowniku) jest bardzo cza-
sochłonne lub wręcz niemożliwe. Rozwiązaniem zadania porządkowania w tym
przypadku powinna więc być permutacja wskaźników elementów porządkowa-
nych. Ponieważ w tym rozdziale zajmujemy się przede wszystkim złożonością
algorytmów, poprzestajemy na ich najprostszych realizacjach. Algorytm porząd-
kujący, który wyznacza permutację wskaźników elementów w miejsce permutacji
samych elementów, jest opisany w zadaniu 7.18.
236
7. Efektywność algorytmów
1
Algorytm naiwny
Podanie naiwnego algorytmu porządkowania nie powinno nikomu sprawić więk-
szego kłopotu. Pamiętamy, jak się wyznacza najmniejszy lub największy element
w ciągu liczb. Wystarczy więc najpierw znaleźć najmniejszy element w ciągu
danych x i przenieść go z a; na początek szukanego ciągu, a w każdym następnym
kroku wyznaczyć najmniejszy element wśród tych, które jeszcze pozostały w x,
usunąć go z a; i dopisać na końcu tworzonego ciągu. Szczegółową realizację tej
metody w języku Pascal polecamy napisać samodzielnie, por. zad. 7.14. Tutaj
wyznaczymy jedynie pracochłonność tego algorytmu, czyli liczbę sprawdzanych
porównań.
Nasz naiwny algorytm wykonuje:
m 1
m-2
2
1
0
porównań w pierwszym kroku,
porównania w drugim kroku,
porównania w kroku (m 2),
porównanie w przedostatnim kroku,
porównań w ostatnim kroku.
Zatem całkowita liczba porównań w naiwnym algorytmie wynosi:
(m - 1) + (m - 2) + ... + 2 + 1 = ((m - 1) + l)(m - l)/2 = m(m - l)/2.
Ten prosty algorytm porządkowania może być ulepszony na wiele różnych
sposobów. Za jedną z takich modyfikacji algorytmu naiwnego można uznać
algorytm bąbelkowy. Każdy krok w tym algorytmie, nazywany przez nas
przebiegiem, polega na przeglądaniu porządkowanego ciągu (a najczęściej tylko
jego fragmentu) i zamianie miejscami każdych dwóch kolejnych elementów, które
nie spełniają nierówności <. Ciągi porządkowane algorytmem bąbelkowym są
najczęściej zapisywane w kolumnie i przeglądane od dołu do góry. Jeśli napo-
tkana liczba jest mniejsza od liczby znajdującej się bezpośrednio nad nią, to
liczby zamieniane są miejscami.
Działanie algorytmu bąbelkowego ilustrujemy na przykładzie zamieszczonym
na rys. 7.2, a jego szczegółową realizację ponownie pozostawiamy do samodziel-
nego wykonania (zad. 7.15). Na rysunku zaznaczyliśmy zamiany między ele-
mentami i oznaczyliśmy liniami poziomymi te miejsca w ciągu, powyżej których
wszystkie liczby są już we właściwym porządku i nie ma potrzeby tego sprawdzać.
W porównaniu z naiwnym algorytmem, który zgodnie z wyznaczoną złożo-
nością wykonałby w tym przypadku 15 porównań, algorytm bąbelkowy wykonał
jedynie 12 porównań (5, 4 i 3 odpowiednio w pierwszym, drugim i trzecim prze-
biegu). Są jednak takie ciągi liczb, dla których algorytm bąbelkowy wykonuje!
taką samą liczbę porównań co naiwny algorytm (por. zad. 7.16). Zauważmy, że
7.5. Porządkowanie przez scalanie
pierwszy
przebieg
drugi
przebieg
trzeci
przebieg
2'
2'
2'
-1 -1
-1
-1
-1
-1
-1
-1 J
0
0
2"
2"
0
o o-l
2
2'
10
10-,
ol
2"
2" 2"
2
" 2"
0 J
10
10
10-, 3
3
3
3
3
3
3 J 10
10
10
237
Rys. 7.2. Ilustracja algorytmu bąbelkowego
po każdym przebiegu algorytmu bąbelkowego przynajmniej jeden nowy element
w porządkowanym ciągu znajduje się na właściwym miejscu. Takich elementów
może być więcej i to jest właśnie źródłem większej efektywności tego algorytmu
(w sensie liczby wykonanych porównań) w porównaniu z naiwnym algorytmem.
Zwróćmy jednak uwagę w tym miejscu na to, że przeciwstawiamy sobie dwie
metody tylko na podstawie liczby sprawdzonych porównań. Z kolei, czasy obli-
czeń wykonanych tymi metodami (por. rozw. zad. 7.21 w EI-II) wskazują na
odmienny charakter ich rzeczywistej pracochłonności. Spowodowane to jest tym,
że w metodzie bąbelkowej, jeśli wynik porównania jest pozytywny, to porównywa-
ne elementy są natychmiast zamieniane miejscami. Ponadto ta ostatnia operacja
jest bardziej czasochłonna niż porównanie i jej liczba w całym algorytmie może
być niewiele mniejsza od liczby porównań.
Zauważmy jeszcze, że algorytm bąbelkowy porządkuje dany ciąg na miejscu
(po łacinie, in situ), tzn. ciąg danych, częściowo uporządkowane ciągi pośrednie
oraz ostatecznie uporządkowany ciąg mogą być pamiętane w jednej i tej samej
tablicy. Tej własności nie ma na przykład operacja scalania (zob. p. 7.3) oraz
wykorzystująca ją metoda sortowania przez scalanie (zob. p. 7.5).
7.5. Porządkowanie przez scalanie
Poznaliśmy już dwa algorytmy porządkowania, które dla wielu ciągów wyko-
nują podobną liczbę porównań. Powstaje zatem pytanie, czy wszystkie metody
porządkowania mają taką samą złożoność. A może istnieją bardziej efektywne
algorytmy? W tym punkcie odpowiemy twierdząco na tę ostatnią wątpliwość,
a na zakończenie rozważań o porządkowaniu wykażemy w p. 7.6, że w pewnym
sensie tego zadania nie można rozwiązywać szybciej.
I
238
7. Efektywność algorytmów
Algorytm, który chcemy teraz opisać, korzysta z algorytmu scalania dwóch
uporządkowanych ciągów opisanego w p. 7.3. Wiemy już, że procedura Scal jest
realizacją optymalnego algorytmu. By móc ją jednak zastosować do porządko-
wania dowolnego ciągu x, musimy określić, które ciągi (uporządkowane) mają
być scalane. Kwestię tę rozstrzygamy dzieląc porządkowany ciąg na dwie nie-
mal równe części, które z kolei są porządkowane ... tym samym algorytmem.
Postępujemy tak aż do momentu otrzymania podciągów jednoelementowych,
które oczywiście są ciągami uporządkowanymi. Wtedy następuje ich scalanie
niejako na drodze powrotnej. Zastosujemy więc rekurencję, o której mówiliśmy
już w p. 3.6 i 4.3. Działanie algorytmu porządkowania przez scalanie jest zilu-
strowane na naszym przykładzie na rysunku 7.3.
(2',-l,2",10,3,0)
dziel
Rys. 7.3. Przykład porządkowania przez scalanie
Zapiszemy teraz ten algorytm w postaci procedury ScalSort i policzymy
jego złożoność. Ponieważ procedura ta ma być wywoływana rekurencyjnie dla
7.5. Porządkowanie przez scalanie
239
podciągów o różnej długości i zaczynających się w różnych miejscach ciągu x, jej
paramatrami są Lewy i Prawy, odpowiednio lewy i prawy koniec porządkowane-
go podciągu. By uporządkować ciąg zapisany w tablicy x[l. .m], należy zatem
wywołać ScalSort (l,in,x).
PROCEDURĘ ScalSort(Lewy,Prawy:INTEGER;VAR x:TablicaR);
VAR Środek:INTEGER;
{Tutaj należy umieścić opis procedury Scal z p. 7.3.}
BEGIN
IF Lewy
ScalSort(Lewy,Środek,x);
ScalSort(Srodek+1,Prawy,x);
Scal(Lewy,Srodek+1,Prawy,x)
END
END; -CScalSort}
Uwaga: Tekst procedury ScalSort znajduje się na dyskietce w pliku SCALSORT.PAS I J i
umieszczonym w kartotece R0ZDZ7.
Pamiętamy z p. 7.3, że złożoność procedury Scal jest równa całkowitej liczbie
elementów w obu łączonych podciągach pomniejszonej o 1. Dla ułatwienia dal-
szych rozważań, których celem jest wyznaczenie złożoności porządkowania przez
scalanie, przyjmujemy, że długość porządkowanego ciągu jest potęgą liczby 2,
tj. istnieje liczba naturalna k taka, że m = 2k. Oznacza to, że w procedurze
ScalSort wszystkie podciągi na tym samym poziomie rekurencji są tej samej
długości, gdyż każdy podciąg jest połową poprzedniego podciągu. Wynika stąd
także, że głębokość rekurencji w tej procedurze wynosi k.
Oznaczmy przez r(m) złożoność procedury ScalSort, czyli liczbę porównań
wykonywanych w trakcie porządkowania m-elementowego ciągu przez scalanie.
Jeśli m = 1, to nie jest wykonywane żadne porównanie, czyli r(l) = 0. Jeśli
m 2, to jest wykonywane jedno porównanie, zatem r(2) = 1. Natomiast
jeśli m > 2, to w algorytmie można wydzielić trzy kroki: dwa z nich polegają
na uporządkowaniu tą samą metodą ciągów o połowę krótszych (odpowiadają
im wywołania procedury ScalSort), a trzeci - to scalanie uporządkowanych
podciągów (za pomocą procedury Scal). Każdy z dwóch pierwszych kroków
ma złożoność r(m/2), a w trzecim jest wykonywanych m/2 4- m/2 1 czyli m l
porównań. W konsekwencji otrzymujemy następującą zależność:
r(m) = 2r(m/2) + m - 1 dla m > 2, (2)
r(2) = 1 i r(l) = 0.
W powyższym wzorze r{rń) jest wyrażone przez tę samą funkcję, lecz dla
mniejszego argumentu. Jest to więc zależność rekurencyjna. Wzór ten ilustruje
240
7. Efektywność algorytmów
dość częstą sytuację w analizie algorytmów, gdy złożoność algorytmu rekurencyj-
nego jest wyrażona zależnością rekurencyjną.
Jawną postać funkcji r(m) można otrzymać korzystając z tego samego wzoru
na policzenie wartości funkcji r dla coraz mniejszych argumentów. W końcu
dochodzimy do wartości m, dla której jest znana wartość liczbowa funkcji r.
Prześledźmy ten sposób wyznaczania r(m). Wstawmy m/2 w miejsce m we
wzorze (2) na r{m) - otrzymamy
r(m/2) = 2r(m/4) + m/2 - 1,
a zatem, po zastąpieniu r(m/2) w wzorze (2) prawą stroną powyższej równości
dostajemy
r(m) = 2(2r(m/4) + m/2 - 1) + m - 1 = 4r(m/4) + 2m - 3.
Jeśli m/4 > 2, to ponownie wykonujemy operacje takie jak powyżej, ale dla
argumentu m/4 we wzorze (2) zamiast m i otrzymujemy
r(m) = 4(2r(m/8) + m/4 - 1) + 2m - 3
= 8r(m/8) + 3m - 7
= 23r(m/23) + 3m - (23 - 1).
Postępujemy tak aż do chwili, gdy argumentem funkcji r po prawej stronie
staje się 2. Wtedy możemy skorzystać z jawnej postaci r(2) = 1. Zauważmy,
że argument funkcji r staje się 2 po k 1 iteracjach (tj. po k 1 wywołaniach
rekurencyjnych). W naszym przypadku, tj. dla m = 2k, otrzymujemy więc
Dzięki szczególnej postaci m mamy 2k~1 = m/2 oraz k = log2 m. A zatem
r(m) = m/2 + (log2 m l)m m/2 + 1,
i ostatecznie, po redukcji wyrazów podobnych, otrzymujemy
r{m) = m log2 m m + 1. (3)
Przypomnijmy, wzór (3) został wyprowadzony przy założeniu, że liczba po-
rządkowanych elementów jest potęgą liczby 2. Jeśli m nie spełnia tego warunku,
to możemy przyjąć, że wartość funkcji złożoności r(m) jest ograniczona przez
7.6. Złożoność algorytmów porządkowania
241
I
i
r(m'), gdzie m' jest najmniejszą potęgą liczby 2 spełniającą nierówność m < m'.
Wynika to z dość oczywistego faktu, że funkcja r(m) jest monotonicznie rosnąca.
Złożoność algorytmu porządkowania przez scalanie jest więc mniejsza niż
złożoność algorytmu naiwnego (nie uwzględniając stałych współczynników i skład-
ników liniowych względem m), gdyż funkcja logarytmiczna spełnia nierówność
log2 m < m. Podobnie wypada porównanie z algorytmem bąbelkowym. O tym
jak duża jest to różnica, świadczą trzy pierwsze kolumny w tablicy 7.1. (Czwarta
kolumna tej tablicy zostanie wykorzystana w dalszych rozważaniach.)
Tablica 7.1.
Wartości trzecr
i funkcji
złożoności
m
m(m- l)/2
r(m)
Iog2(m!)
23
8
28
17
16
24
16
120
49
45
25
32
496
129
118
26
64
2016
321
296
100
4950
566
525
27
= 128
8128
769
717
200
19900
1330
1246
28
= 256
32640
1793
1684
7.6. Niezbędna liczba porównań w algorytmach
porządkowania
Uzasadnimy teraz, że algorytm porządkowania przez scalanie jest w pewnym
sensie optymalny. A dokładniej, wykażemy, że funkcja złożoności obliczeniowej
każdej innej metody porządkowania zawiera składnik, który ze wzrostem m rośnie
co najmniej tak szybko, jak funkcja mlog2 m występująca we wzorze (3).
Przypomnijmy, że zadanie uporządkowania ciągu x = (xi, X2, , xm) polega
na znalezieniu takiej permutacji (i\,i2, ? ? ? ,im) ciągu wskaźników (l,2,...,m),
dla której mamy x^ < Xi2 < ... < Xim. Łatwo się przekonać, że rozwiązaniem
problemu porządkowania może być dowolna permutacja, której postać zależy od
wartości porządkowanych elementów. Na przykład, dla m = 6, jeśli rozwiązaniem
ma być permutacja (3,5,1,4,6,2), to za porządkowany ciąg wystarczy przyjąć
(3, 6,1,4, 2, 5). Zależność między tymi dwoma ciągami ilustruje diagram:
(xh,xi2,...,Xim) =361425
(ii,i2,-.-,im) =351462
16 Elementy informatyki
242
7. Efektywność algorytmów
Zatem dla ustalonej długości m porządkowanego ciągu x liczba możliwych
rozwiązań problemu porządkowania jest równa liczbie wszystkich permutacji cią-
gu (1,2,..., m). Ta liczba zaś jest równa m! (czytaj m silnia) i wynosi
m! = 1 2- ... (m- 1) -m.
Tablica 7.2. ilustruje szybkość wzrostu funkcji m! ze wzrostem m. Ponadto,
w trzeciej kolumnie są podane czasy wykonania m! operacji przez komputer
działający z szybkością 1 miliarda (tj. 109) operacji na sekundę. Zbudowano
już takie komputery - nazywamy je superkomputerami - jest nim na przykład
Cray 4, który wykonuje 100 miliardów operacji na sekundę.
Tablica 7.2. Wartości silni
m
m!
Czas obliczeń
10
15
20
25
3628800
1.3E+12
2.4E+18
1.55E+25
0.0036 s
21.8 min
77 lat
496E+6 lat
Funkcja m! jest rzeczywiście bardzo szybko rosnąca. W związku z tym po-
winniśmy unikać obliczeń, w których liczba działań, w zależności na przykład od
długości danych m, jest proporcjonalnie związana z m\. Zauważmy, że w przy-
padku porządkowania, chociaż liczba możliwych rozwiązań wynosi ml, to jednak
potrafimy znaleźć właściwe uporządkowanie znacznie szybciej, na przykład me-
todą bąbelkową o złożoności co najwyżej m2.
Przejdźmy teraz do wyprowadzenia zapowiedzianego wniosku. Na początku
zilustrujmy wszystkie możliwe drogi działania algorytmu porządkującego trzy
liczby a, b i c. W tym celu posłużmy się drzewem obliczeń, w którym zawrzemy
wykonywane operacje (w naszym przypadku są nimi porównania) i możliwe wy-
niki działania algorytmu (por. rys. 7.4).
Każde inne drzewo porządkujące ciąg liczb o ustalonej długości ma z tym
drzewem przynajmniej dwie cechy wspólne:
- z wierzchołka pośredniego wychodzą na dół dokładnie dwie krawędzie,
- wierzchołki końcowe zawierają wszystkie możliwe permutacje porządko-
wanego ciągu.
Ta pierwsza własność wynika stąd, że wierzchołki pośrednie w drzewie za-
wierają porównania, a rezultatem wykonania tej operacji jest jedna z dwóch
możliwych odpowiedzi: Tak (T) lub Nie (N). Operacje takie nazywają się bi-
narnymi, a drzewo obliczeń złożonych z operacji binarnych nazywa się drze-
wem binarnym. Druga zaś własność jest związana z tym, że każdy algorytm
7.6. Złożoność algorytmów porządkowania
243
korzeń ?- a < b
Tak
wierzchołki
pośrednie
(c,a,b)
wierzchołki-------?? (a, b, c) (a, c, b) (b, c, a) (b, a, c)
końcowe
Rys. 7.4. Drzewo algorytmu porządkującego trzy liczby
porządkujący musi uwzględniać wśród swoich wyników wszystkie możliwe ko-
lejności porządkowanych elementów. Możemy więc przyjąć, że z dowolnym al-
gorytmem porządkowania m liczb jest związane drzewo binarne, które ma co
najmniej m! wierzchołków końcowych.
Zastanówmy się teraz, co odpowiada złożoności algorytmu w tym modelu
porządkowania. Powróćmy do ilustracji z rys. 7.4. Algorytm tam przedstawiony
wykonuje dwa porównania, gdy wynikami są uporządkowania (c,a,b) i (c,b,a),
a trzy porównania w pozostałych przypadkach. Liczba porównań sprawdzonych,
by otrzymać wynik w ustalonym wierzchołku końcowym, jest więc równa liczbie
wierzchołków pośrednich na drodze z korzenia do tego wierzchołka. Uzasadnia to
przyjęcie za złożoność algorytmu przedstawionego w postaci drzewa liczby wierz-
chołków w najdłuższej drodze z korzenia do wierzchołka końcowego - wielkość
tę nazywamy w drzewie jego wysokością. Zatem złożoność algorytmu, któremu
odpowiada drzewo z rys. 7.4 jest równa wysokości tego drzewa i wynosi 3. Za-
uważmy, że w niektórych przypadkach obliczeń, algorytm może wykonywać mniej
operacji niż wynosi jego złożoność, ale nigdy więcej. Przyjęte przez nas określenie
złożoności algorytmu nazywa się pesymistyczną złożonością, gdyż jest ona
największą liczbą wykonywanych operacji, wziętą po wszystkich możliwych wy-
nikach działania algorytmu przy ustalonej długości danych. Z podobną sytuacją
spotkaliśmy się już przy scalaniu ciągów.
Podsumujmy dotychczasowe rozważania. Dowolny algorytm porządkujący m
liczb, którego podstawową operacją jest porównanie dwóch liczb, można przed-
244
7. Efektywność algorytmów
stawić w postaci drzewa binarnego z przynajmniej m\ wierzchołkami końcowymi,
a za jego złożoność przyjmujemy wysokość tego drzewa. Zatem drzewo o mniej-
szej wysokości odpowiada lepszemu (tj. szybszemu) algorytmowi. Pokażemy, że
takie drzewo nie może mieć mniejszej wysokości niż log2m!.
Prześledźmy najpierw na kilku przykładach (por. rys. 7.5.), jak wyglądają
najniższe drzewa binarne o liczbie wierzchołków końcowych 2, 3,4, 5 i 6. Drzewa te
konstruujemy w taki sposób, że do następnego poziomu przechodzimy dopiero po
wypełnieniu poprzedniego. Za poziom w drzewie binarnym przyjmujemy zbiór
tych wierzchołków, dla których droga do korzenia ma taką samą liczbę wierz-
chołków pośrednich. Zauważmy, że każdy poziom może mieć co najwyżej dwa
razy więcej wierzchołków niż poprzedni, a zatem kolejne poziomy w najniższych
drzewach binarnych zawierają 1, 2, 22, 23, 24,... wierzchołków.
Rys. 7.5. Najniższe drzewa binarne
Aby policzyć, ile poziomów musi mieć drzewo zawierające m! wierzchołków
końcowych, skorzystamy z prostego faktu, że każde drzewo binarne o n wierz-
chołkach końcowych ma n 1 wierzchołków pośrednich. Przykłady drzew bi-
narnych z rys. 7.4 i 7.5. potwierdzają ten fakt, a indukcyjny dowód ogólnej
własności pozostawiamy do samodzielnego wykonania (por. zad. 7.20). Zatem
drzewo binarne o przynajmniej m! wierzchołkach końcowych ma co najmniej
2ml 1 wszystkich wierzchołków. Ponieważ drzewo o k poziomach ma co najwyżej
1 + 2 + 2 + ... + 2 wszystkich wierzchołków, zatem musimy znaleźć najmniejsze
k spełniające nierówność:
2m! - 1 < 1 + 2 + 22
Zadania
245
Zsumujmy prawą stronę jako szereg geometryczny o ilorazie 2, wykonajmy
zaznaczone działania i zlogarytmujmy obie strony:
2m! -
2m! -
2fc+1 -
m!
log2 ml < k
Zatem drzewo binarne o przynajmniej m! wierzchołkach końcowych ma wy-
sokość co najmniej log2 ml. Ten sam wniosek w języku algorytmów porządkowa-
nia sformułujemy jako twierdzenie.
Twierdzenie 7.2. Jakikolwiek algorytm porządkowania m liczb wykonuje co naj-
mniej log2 m\ porównań między elementami porządkowanego ciągu.
Wyrażenie log2 ml jest w przybliżeniu równe mlog2m (wynika to ze wzoru
Stirlinga na przybliżoną wartość ml, którego tutaj nie podajemy), a jego wartości
dla kilku m są podane w tablicy 7.1. Przy okazji porównajmy wartości w czwartej
kolumnie tablicy 7.1 z odpowiednimi wartościami w kolumnach drugiej i trzeciej
- te pierwsze rzeczywiście ograniczają od dołu złożoności algorytmów naiwnego
i przez scalanie, którym odpowiadają dwie środkowe kolumny,
Powróćmy na zakończenie do procedury ScalSort. Z jednej strony wy-
kazaliśmy, że jej złożoność wynosi mlog2m m + 1. Z drugiej zaś, wartość
tego wyrażenia w porównaniu z wartością log2 m! różni się jedynie składnikiem
rosnącym wolniej. Mamy więc podstawy stwierdzić, że algorytm porządkowania
przez scalanie jest optymalny z dokładnością do stałego współczynnika.
Uzupełnieniem rozważań o złożoności algorytmów porządkujących i potwier-
dzeniem postaci otrzymanych dla nich funkcji złożoności mogą być obliczenia te-
stowe przeprowadzone z komputerowymi realizacjami algorytmów (por. zad. 7.21).
Zadania
7.1. Dobierz takie wartości liczb naturalnych a i b, aby algorytm Euklidesa wyko-
nywał możliwie dużą i możliwie małą liczbę kroków. Wszystkie obliczenia prze-
prowadź bez użycia komputera.
7.2. Zmodyfikuj opis funkcji Suma w programie CzasSumowania tak, by ta nowa
funkcja działała poprawnie nawet wtedy, gdy m=0. Jaka jest złożoność zmodyfi-
kowanej funkcji?
7.3. Zmodyfikuj program CzasSumowania tak, aby obliczał sumę liczb umieszczo-
nych w pliku.
246
7. Efektywność algorytmów
7.4. Przyjmij, że dysponujesz sześcioma algorytmami Ai,A%,... ,Aq, które wy-
I
konują odpowiednio lOOOre, 100nlog2n, lOn
n , n
i 2n podstawowych operacji,
by wyznaczyć rozwiązanie problemu określonego za pomocą n danych.
a. Policz, ile czasu zajmie wykonanie obliczeń tymi algorytmami dla n =
10, 20, 50, 100, 500,1000 danych za pomocą komputera, który liczy z szybkością
100 min operacji na sekundę.
b. Przyjmij, że Sj jest największym rozmiarem (tj. liczbą danych) zadania,
jakie możesz rozwiązać na swoim komputerze używając algorytmu Ai i określ,
0 ile wzrośnie rozmiar zadań rozwiązywalnych tym algorytmem, gdy wymienisz
komputer na dziesięć razy szybszy.
Uwaga: Zadanie to ma Cię przekonać, że większe korzyści można mieć z polep-
szania (czyli przyspieszania pracy) algorytmów niż z przyspieszania pracy kom-
puterów, co staje się bardzo kosztowne i trudno oczekiwać, by szybkość pracy
komputerów dawało się tak często polepszać i to aż o tak wiele jak rząd wielkości.
7.5. Wykonaj obliczenia programem CzasSumowania na swoim komputerze (naj-
lepiej innym niż IBM PC/XT lub AT). Czasy działania otrzymane dla różnych m
nanieś na wykres z rys. 7.1 i dopasuj do nich prostą określoną wzorem (1). Policz
jej współczynniki i porównaj ze współczynnikami prostych z rysunku 7.1.
7.6. Zrealizowany w funkcji Suma algorytm obliczania sumy m liczb nazywa się
metodą od-lewej-do-prawej, gdyż liczy sumy częściowe począwszy od x\ i po-
suwa się na prawo ku xm. Rozważ metodę obliczania wartości sumy, w której na
każdym kroku są dodawane do siebie dwie sąsiednie liczby. Zatem po pierwszym
kroku sumowany ciąg składa się z [m/2] liczb i powtarzamy to postępowanie
aż pozostanie jeden element. (Wyrażenie [m/2] jest równe najmniejszej liczbie
całkowitej, równej lub większej niż m/2). Przekonaj się, że jest nim wartość sumy
dodawanych elementów. Na przykład, z ciągu (3, 7,4, 5, 9) po pierwszym kroku tej
metody pozostaje ciąg (3 + 7,4+5,9) = (10, 9, 9), po drugim - (10+9,9) = (19,9)
1 ostatecznie otrzymujemy 28. Określ, ile dodawań w zależności od m wykonuje
ten algorytm i zapisz go jako procedurę w języku Pascal.
7.7. Dowolny algorytm sumowania można przedstawić w postaci drzewa obli-
czeń, które składa się z wierzchołków i krawędzi między nimi. W wierz-
chołkach zwanych końcowymi znajdują się argumenty działań, a w wierzchołkach
pośrednich - działania. Krawędzie zaś odzwierciedlają kierunek przebiegu in-
formacji w algorytmie. Na rysunku 7.6 jest zilustrowany algorytm dodawania
sześciu liczb metodą od-lewej-do-prawej. Narysuj drzewa obliczeń dla algorytmu
z zadania 7.6 dla m = 5, 6, 7, 8.
7.8. W jakich przypadkach procedura Scal wykonuje najmniej porównań, a kiedy
najwięcej? Postaraj się przekonująco uzasadnić swoją odpowiedź.
Zadania
247
Xl X2
Rys. 7.6. Drzewo dodawania od-lewej-do-prawej
7.9. Wartość jakiego wyrażenia liczy następujący ciąg instrukcji?
s:=0.0;
FOR i:=l TO m DO
s:=s+3.0*x[i]*y*SIN(3.0*3.1415926/2.0)
Zmodyfikuj ten fragment tak, by działał szybciej. Sprawdź na swoim komputerze,
jaki osiągnąłeś zysk na czasie dla różnych wartości m. Sformułuj ogólny wniosek.
7.10. Uzupełnij opis funkcji Min o dodatkowe instrukcje wyznaczające jedno-
cześnie wskaźnik minimalnego elementu w tablicy x.
7.11. Funkcja Min przez prostą zmianę zwrotu nierówności w instrukcji warun-
kowej, może być użyta do wyznaczania maksimum, czyli elementu o największej
wartości w ciągu x. Zatem obie wielkości - minimum i maksimum spośród m liczb
- można znaleźć za pomocą 2(m 1) porównań. Zauważ, że w tym przypadku
wielkości te są wyznaczane niezależnie jedna od drugiej. Zaproponuj natomiast
algorytm jednoczesnego znajdowania min oraz max, który wykonuje ["3m/2~| 2
porównań i zapisz go w języku Pascal.
Wskazówka: Skorzystaj z następującego spostrzeżenia, które najpierw uzasa-
dnij: porównując dwa elementy ze sobą, można zawsze jeden z nich wyeliminować
ze zbioru kandydatów na minimum, a drugi - spośród kandydatów na maksimum.
7.12. Wykaż indukcyjnie, że liczba wszystkich permutacji rn elementowego ciągu
jest równa m\ = 1 ? 2 ... ? m.
Wskazówka: Skorzystaj z metody generującej permutacje m-elementowe z per-
mutacji (m l)-elementowych.
248
7. Efektywność algorytmów
i
7.13. Algorytm koszykowy jest stosowany do porządkowania elementów, którym
można przyporządkować wartości będące liczbami naturalnymi z przedziału od 1
do n, gdzie n jest małą liczbą w porównaniu z długością ciągu rn. Algorytm ten
ma następującą postać:
1. Zainicjuj n koszyków po jednym dla każdej liczby z przedziału od 1 do n.
2. Przeglądaj elementy ciągu danych i wkładaj je do odpowiednich koszyków,
element o wartości i włóż do i-tego koszyka.
3. Ustaw elementy z kolejnych koszyków w jeden ciąg, biorąc najpierw ele-
menty z koszyka o numerze 1, po nich element z koszyka o numerze 2,
następnie elementy z koszyka o numerze 3 itd.
Otrzymany tym algorytmem ciąg jest oczywiście uporządkowany niemalejąco
względem wartości elementów. Napisz procedurę w języku Pascal realizującą ten
algorytm, w której koszyki są reprezentowane przez listy utworzone za pomocą
typu wskaźnikowego. Przyjmij, że podstawowym działaniem w algorytmie jest
przeniesienie elementu z miejsca w miejsce (w języku Pascal przeniesieniu odpo-
wiada przypisanie). Określ złożoność podanej procedury (czasową i pamięciową)
jako funkcję zmiennych m i n. Jaka byłaby złożoność realizacji algorytmu koszy-
kowego, gdyby koszyki były pamiętane w tablicach, a nie w listach.
7.14. Napisz procedurę w języku Pascal realizującą naiwny algorytm porząd-
kowania. W jej treści skorzystaj ze zmodyfikowanej funkcji Min, która zamiast
elementu najmniejszego w ciągu znajduje jego wskaźnik. Postaraj się by Twoja
procedura porządkowała in situ.
7.15. Napisz procedurę BabelSort realizującą algorytm bąbelkowy. Jako jeszcze
jedno usprawnienie przyjmij, że w kolejnym przebiegu algorytmu jest sprawdzane
spełnienie nierówności < wśród elementów od najniżej położonego do najwyższego
(włącznie) spośród tych, które zostały przestawione w poprzednim przebiegu.
Uzasadnij poprawność tego uproszczenia.
7.16. Podaj przykład ciągu, dla którego algorytm bąbelkowy wykonuje tyle samo
porównań co algorytm naiwny. Postaraj się uogólnić swój przykład na ciąg o m
elementach, gdzie m może być dowolną liczbą.
7.17. Przeanalizuj złożoność algorytmu porządkowania, w którym na każdym
kroku są scalane ciągi o długościach 1 i m 1. Opisz także ten algorytm bez
korzystania z operacji scalania.
7.18. Przyjmij, że elementy, które mają być uporządkowane, są zapisane w ta-
blicy typu CiagDanych złożonej z m składowych typu Element, zdefiniowanych
następująco:
TYPE Element=RECORD
Klucz
:REAL;
Zadania
249
{inne pola}
Wskaźnik:IMTEGER
END;
CiagDanych=ARRAY[l..m] OF Element
Napisz procedurę porządkującą metodą scalania ciąg liczb umieszczony w tablicy
x typu CiagDanych, której elementy nie zmieniają swojego miejsca, a ich kolejność
jest wskazywana wartościami pól Wskaźnik. Dla naszego przykładu z p. 7.4 po-
winniśmy więc otrzymać reprezentację pokazaną na rys. 7.7. Zatem procedura po-
Klucz
-1
Wskaźnik
Rys. 7.7. Ilustracja do zadania 7.18
winna dodatkowo określać wskaźnik do pierwszego elementu w uporządkowanym
ciągu, w naszym przykładzie jest nim 2. Zauważ, że ciąg kolejnych wskazań
(w naszym przykładzie: 2, 6,1, 3, 5,4) jest permutacją wskaźników (ii, %2, ? ? ?, im)
określającą szukane uporządkowanie.
7.19. Napisz procedurę scalającą dwa uporządkowane ciągi dane w plikach p i q.
7.20. Wykaż indukcyjnie, że każde drzewo binarne z n wierzchołkami końcowymi
ma n 1 wierzchołków pośrednich.
Wskazówka: Zastanów się najpierw, jak można otrzymać drzewo binarne za-
wierające n wierzchołków końcowych z drzewa on-1 wierzchołkach końcowych.
7.21. Przeprowadź eksperyment obliczeniowy z poznanymi algorytmami porząd-
kowania: naiwnym, bąbelkowym i przez scalanie. W tym celu umieść procedury
realizujące te algorytmy w jednym programie, który wyznacza ich czas działania
dla tych samych danych. Jako dane przyjmij ciągi o długościach m = 50, 100, 300,
500, 1000 złożone z losowo generowanych liczb. Wyznacz także czasy działania
procedur na ciągach uporządkowanych i ciągach w odwrotnej do szukanej ko-
lejności (bardzo często są to ciągi, dla których algorytmy porządkujące wykonują
najmniejszą lub największą liczbę operacji).
I
8. BEZ KARTKI I OŁÓWKA -
PRZETWARZANIE TEKSTÓW
8.1. O sztuce opracowywania tekstów
W tym rozdziale zajmiemy się wykorzystaniem komputerów do redagowania
tekstów. Ponieważ mamy już za sobą niejeden napisany program (w języku
Logo lub Pascal), nie możemy nie zauważyć, że z komputerowym redagowaniem
tekstów spotkaliśmy się już uprzednio, niejako mimochodem i z konieczności. Te-
raz poświęcimy temu więcej uwagi. Przez redagowanie tekstu (w szczególności
za pomocą komputerów) będziemy rozumieli rozwiązywanie technicznych pro-
blemów opracowywania tekstu, w odróżnieniu od redagowania merytorycznego,
to jest uzgadniania treści. Mimo że redagowanie merytoryczne i redagowanie
techniczne są odrębne, jak pomyślenie słowa i jego napisanie; łatwość pisania
z pomocą komputerów ma wpływ zarówno na jedną, jak i drugą stronę opra-
cowywania tekstów. Lektura tego rozdziału, połączona z pewną dozą własnych
doświadczeń z komputerem, pozwoli określić, na czym polegają zalety użycia
komputera.
Aby przygotować dobre wypracowanie, dowolną pisemną wypowiedź (list,
podanie, artykuł, mowę itd.) musimy znać temat, który ma być przedstawiony,
słownictwo oraz zasady gramatyki, ortografii i interpunkcji języka, a także jego
stylistyki, frazeologii (tu również przydaje się znajomość odbiorcy, do którego się
zwracamy) i innych elementów pisarskiego warsztatu (zob. zad. 8.1, 8.2).
Nawet przy spełnieniu tych wymogów redagowanie tekstu w postaci ciągu
zdań czy - w przypadku dłuższych tekstów - ciągu akapitów, paragrafów lub
rozdziałów pozostaje nadal złożonym i trudnym zadaniem. Mało kto potrafi,
wypróbowując warianty w pamięci, przelewać na papier treści w formie zbliżonej
do tej, jaką uznałby za ostateczną. Jest to naturalne, a dowody można odnaleźć
w niejednej bibliotece czy muzeum, gdzie efekty zmagania się z formą przez uzna-
nych ludzi pióra lub nauki są udokumentowane w postaci pokreślonych, z trudem
czytelnych rękopisów (zob. zad. 8.3).
8.2. Komputerowe redagowanie tekstu
251
Oprócz redagowania wypracowań, które w wieku szkolnym ćwiczą nasze u-
miejętności uporządkowanego formułowania myśli, redagowanie różnych tekstów
pochłania coraz więcej czasu coraz większej liczbie ludzi różnych zawodów. Po-
nadto okazuje się, że poza literaturą piękną, dziełami naukowymi, publicystyką
itp. sporo tekstów powstających w związku z handlem i zarządzaniem ma szablo-
nowy charakter, co nie oznacza, iż mogą one wykazywać niedopracowaną formę.
Jednocześnie typowość tego rodzaju tekstów pozwala na automatyzację ich przy-
gotowywania również pod względem treści (zob. zad. 8.4, 8.5).
Maszyna do pisania od chwili wynalezienia (H.R. Malling-Hansen, 1867) prze-
szła liczne modyfikacje: od "jednopalcowego" pradziadka Mignona, poprzez różne
mechaniczne Ideale, elektryczne Optimy, aż do współczesnych maszyn IBM wy-
posażonych w pamięć i wymienne głowice z różnymi krojami pisma.
Mimo wielu zmian i ulepszeń maszyna do pisania zautomatyzowała zada-
nie właściwie tylko w odniesieniu do stawiania poszczególnych liter. Tam, gdzie
oprócz przepisywania czy wpisywania w rubryki są potrzebne liczne zmiany oraz
przekształcenia tekstu, czyli w złożonym procesie jego redagowania, maszyna do
pisania przestaje być wygodnym narzędziem. W tym ostatnim wypadku brakuje
jej elastyczności układu kartki i ołówka - z możliwością dokonywania skreśleń.
Współczesny nam okres rozwoju środków technicznych usprawniających re-
dagowanie tekstów można postrzegać jako przeobrażanie się maszyny do pisania,
uwieńczone specjalizowanym komputerem i uniwersalnymi programami zwanymi
edytorami lub procesorami tekstu.
Komputery zastosowane do redagowania tekstów nie tylko naśladuj ą własności
mechanicznych maszyn do pisania. Teksty przechowywane w pamięci komputera
można kształtować nader elastycznie. Wprowadzanie poprawek i ulepszeń jest
uproszczone. Odpowiednie środki techniczne umożliwiają posługiwanie się wie-
loma alfabetami i krojami pisma.
Komputerowe maszynopisanie, a mówiąc dokładniej - przetwarzanie tek-
stów, stało się jednym z ważniejszych zastosowań komputerów osobistych. Kom-
putery wprowadzają nową jakość w od wieków aktualne cyzelowanie tekstów.
8.2. Redagujemy tekst za pomocą komputera
Dalej przedstawimy proces redagowania tekstu na przykładzie edytora TAG, bę-
dącego w powszechnym użyciu na komputerach osobistych IBM PC, w tym także
na szkolnych komputerach.
Nazwa edytora TAG pochodzi od imion jego konstruktorów (Tomasz, Artur,
Grzegorz). Jest to, obok edytora ChiWriter, jeden z najpopularniejszych obe-
cnie programów redagowania tekstów używanych w Polsce. Edytor TAG daje
bogaty przegląd możliwości komputerowych edytorów tekstu. Dalsze rozważania
252
8. Przetwarzanie tekstów
są w znacznym stopniu ilustrowane operacjami zaczerpniętymi wprost z tego edy-
tora. Podany dalej opis poszczególnych działań edytora TAG odnosi się zarówno
do wczesnych, jak i do późniejszych wersji tego programu.
Należy jednak zdawać sobie sprawę z tego, że w innych edytorach operacje
podobne z logicznego punktu widzenia mogą być realizowane za pomocą innych
rozwiązań technicznych, jak również z tego, że najbardziej interesuje nas przegląd
różnorodnych działań użytecznych w przetwarzaniu tekstów. Opisu wszystkich
własności edytora TAG należy szukać w jego dokumentacji firmowej, natomiast
pełny spis cech odnajdywanych we współczesnych edytorach liczy blisko 300 po-
zycji. Kompromis, jaki tu stosujemy, polega na omawianiu najważniejszych cech
większości edytorów na przykładzie jednego edytora i wybranych własności innych
edytorów, których edytor TAG nie zawiera.
Edytor TAG zajmuje miejsce pośrednie między ograniczonymi typograficznie
edytorami przeznaczonymi do pisania programów (które, ze wględu na używany
przez nie zbiór znaków możemy określić wspólnie mianem edytorów tekstów
ASCII), a skomplikowanymi systemami składu drukarskiego, takimi jak TęX
lub Ventura, za pomocą których składa się obecnie na komputerach całe książki.
Na przykład, ta książka została złożona przez autorów za pomocą systemu TgX.
Zredagowanie i wydrukowanie książki jest również możliwe za pomocą edy-
tora TAG, oszczędniejszymi jednak środkami wyrazu. Opanowanie umiejętności
posługiwania się nim pozwala na opracowywanie dowolnych tekstów oraz rozwija
intuicję pomocną w kontaktach z innymi edytorami. Edytor TAG może również
służyć do pisania tekstów w kodzie ASCII - na przykład programów w Pascalu,
C lub w innych językach programowania. Należy jednak pamiętać, że - podobnie
jak w przypadku składu drukarskiego - do pisania dużych programów używa się
innych edytorów. Prostym sprawdzianem przydatności edytora do pisania pro-
gramów jest sposób wykonywania typowych operacji, np. liczba naciśnięć klawi-
szy potrzebna do zamiany miejscami dwu wierszy tekstu. Inną ważną cechą edy-
tora programów jest możliwość łatwego działania na wielu plikach jednocześnie.
Podobnie jak w maszynach do pisania edytory przeznaczone do redagowa-
nia tekstów artykułów, wypracowań itp. pozwalają użytkownikowi określać takie
parametry druku jak:
- szerokość wiersza tekstu, liczoną w znakach;
- wysokość wiersza liczoną w minimalnych wysuwach pionowych pa-
pieru, tzw. ząbkach (lub rządkach) - typowy wiersz ma 3 lub 4 ząbki wy-
sokości; w przypadku edytorów współpracujących z drukarkami laserowymi
możliwości przestrzennej kompozycji tekstu są o wiele bogatsze (stosuje się
w nich zarówno miary tekstu w punktach zecerskich, jak i miary calowe
oraz metryczne);
- wysokość strony, liczoną w wierszach lub elementarnych wysuwach;
1.2. Komputerowe redagowanie tekstu
253
krój pisma (rys. 8.1), który może być dowolnie zmieniany w trakcie pisa-
nia.
Standard
pismo pogrubione
kursywa, czyli pismo pochyłe
pismo maszynowe
Pismo bezszeryfowe
Pismo Wielkie
znaki specjalne: ż & # 0 ...
Rys. 8.1. Kroje pisma spotykane w edytorach tekstu
W przypadku edytora TAG jest możliwe m.in. zwiększanie wysokości lub
poszerzanie kroju pisma. Ogólnie, wybór czcionki w edytorze TAG polega na
dokładaniu atrybutów do kroju podstawowego. Można więc zażądać, aby zwy-
kłe proste litery stały się pochyłe {kursywa), po czym także pogrubione, a nas-
tępnie jeszcze poszerzone itd. I na odwrót, krojowi, który został powiększony
i poszerzony oraz pochylony i podkreślony można ująć atrybutów, by w końcu
zamienić go na elegancki, choć skromny krój bezszeryfowy. Do ustalania kroju
pisma służą klawisze | Fl | i |F2 |. Istnieje możliwość obejrzenia poszczególnych
krojów pisma i zbiorów znaków na ekranie (klawisze |F2 |, |F9 |naciśnięte kolejno
po sobie). TAG umożliwia w szczególności użycie cyrylicy.
W edytorze TAG użytkownik może - zupełnie jak w zwykłej maszynie do
pisania - swobodnie ustawiać marginesy, miejsca tabelacji, określać sposób nu-
merowania stronic itp. Czynności te nazywają się w edytorze TAG ustala-
niem wzorca i zwykle poprzedzają polecenie drukowania. Można je wykonać
po naciśnięciu klawisza | F3 |. Pojedynczy redagowany moduł tekstu musi się
zmieścić w 64 kB pamięci, czyli w około 64 tys. bajtów. Ograniczenie to rzadko
daje znać o sobie, ponieważ edytor TAG umożliwia budowanie z modułów tekstu
hierarchii rozdziałów i punktów. Jeśli jednak dojdzie do sygnalizacji braku miej-
sca na pomieszczenie znaków modułu, użytkownik ma okazję zastanowić się, czy
jego tekst nie powinien zostać napisany strukturalnie, zamiast w postaci nieprze-
rwanego potoku zdań nie podzielonego na żadne jednostki logiczne.
254
8. Przetwarzanie tekstów
8.3. Uruchomienie edytora
Edytor TAG rozpoczyna pracę po wydaniu zlecenia TAG, uzupełnionego ewentu
alnie nazwą pliku zawierającego tekst, który ma być redagowany. Na przykła
można wywołać
TAG C:\TEKSTY\ESEJ
gdzie ESEJ jest nazwą pliku z katalogu TEKSTY z tomu dyskowego C:.
Pliki edytora TAG przyjmują rozszerzenia TAG, wobec czego powyższe zlecenie
zostanie zinterpretowane następująco:
TAG C:\TEKSTY\ESEJ.TAG
Uruchomienie edytora TAG może zależeć od specyfiki instalacji komputera
IBM PC, w szczególności od zawartości listy automatycznie przeszukiwanych kar-^
totek (por. informacje o systemie operacyjnym MS-DOS w rozdz. 2) i obecności
odpowiednich makrodefinicji. Jeśli, na przykład, umieściliśmy w pliku ED.BAI
ciąg zleceń:
C:
CD \TAG
TAG C:\TEKSTY\7.1
to wtedy identyczny efekt jak wyżej osiągniemy wydając zlecenie
ED ESEJ
Po uruchomieniu edytora na ekranie pojawiają się dwie ramki. W ramce po i
prawej stronie jest wyświetlana metryczka programu (dane o wersji, nazwiska ]
autorów itp.), a w prawym górnym rogu pojawia się numer seryjny edytora. DL
użytkownika najistotniejsza jest ramka po lewej stronie, w której wykonuje si|
działania zaliczane do warstwy wyboru plików.
8.4. Trzy warstwy edytora TAG
Edytor TAG jest dobrym przykładem realizacji projektu logicznych warstw
oprogramowania. Użytkownik po uruchomieniu edytora wchodzi w warstwę
wyboru plików. Na tym poziomie wybiera plik, który chce przetwarzać. Nastę-
pnie przechodzi do warstwy hierarchii tekstu, w której rozstrzyga o ogólnej i
strukturze redagowanego dokumentu, jego podziale na części, rozdziały, para-j
grafy itp. Dopiero po określeniu warunków pracy w obu wstępnych warstw
użytkownik przechodzi do zasadniczej warstwy redagowania tekstu. Wy
chodzenie z warstw edytora odbywa się w odwrotnej kolejności. Do głębszych
8.4. Trzy warstwy edytora TAG
255
warstw przechodzi się naciskając klawisz | Enter | lub | Ins |. Wyjście na poziom
zewnętrzny następuje po dwukrotnym naciśnięciu klawisza | Esc |.
Warstwy edytora i związki między nimi odzwierciedlają logiczną kolejność
działań przy redagowaniu tekstów:
- najpierw zdecyduj, jaki tekst chcesz redagować,
- następnie określ jego ramową strukturę,
- po czym wykonaj prace redakcyjne nad tekstem.
W praktyce, w czasie jednej sesji przechodzi się wielokrotnie z jednej warstwy
do innej i z powrotem. Jeżeli tekst jest niewielki (na przykład jednostronicowe
podanie), to warstwę hierarchii tekstu przechodzi się bez specjalnego namysłu.
W każdej warstwie można wykonać podstawową - z punktu widzenia zabez-
pieczenia danych - operację, jaką jest zapamiętanie stanu pracy (czyli redagowa-
nego tekstu w aktualnej postaci) na dysku, naciskając dwukrotnie klawisz [F8 |.
Warstwa wyboru plików
W warstwie wyboru użytkownik wybiera plik, który chce redagować. W tym celu
może albo jawnie podać nazwę pliku, albo wskazać za pomocą kursora plik znaj-
dujący się na wyświetlanej liście. W tym drugim przypadku można uprzednio
skorzystać z możliwości zmiany tomu dyskowego lub bieżącej kartoteki, selekcjo-
nowania plików według podawanych przez siebie szablonów itp. Informacja o do-
konywanych w danej chwili czynnościach i służących do ich wywołania klawiszach
jest zawsze umieszczana wprost na ekranie. Warto także pamiętać o roli klawisza
I Tab |, którego naciśnięcie powoduje przemieszczanie się między poszczególnymi
segmentami ramek.
Po wybraniu - przez naciśnięcie klawisza | Enter | lub | Ins [ - pliku już ist-
niejącego na którymś z dysków lub określeniu nazwy nowego pliku (co można
zrobić już przy uruchamianiu systemu TAG), po prawej stronie ekranu jest wy-
świetlana ramka z metryczką pliku. W dolnej części okna pojawiają się stan-
dardowe informacje o pliku (rozmiar, data założenia i ostatniej jego aktualizacji
itp.). Górna część metryczki może zostać przez użytkownika wypełniona dodat-
kową, ogólną informacją o pliku.
Warstwa hierarchii tekstu
Po zatwierdzeniu przez akceptację metryczki wyboru pliku (za pomocą klawisza
| Enter | lub | Ins |) następuje przejście w warstwę hierarchii tekstu. Z tego po-
ziomu można wydrukować tekst (klawisze | Fl | i |F2 |), natomiast najciekawsza -
z punktu widzenia pracy nad tekstem - jest oferta wyświetlana po naciśnięciu kla-
wisza | F4 |, umożliwiająca działania na strukturze tekstu. W zależności od przyję-
tej metody pracy nad tekstem (najpierw utworzenie ogólnego szkicu-konspektu,
256
Przetwarzanie tekstów
i
bądź też najpierw wpisanie treści szczegółowej) z oferty tej można skorzystać
na samym początku lub później. W praktyce powraca się do niej wielokrot-
nie, opracowując tekst (w tym - jego strukturę) na zasadzie kolejnych ulepszeń.
Użytkownik ma możliwość swobodnego rozplanowania swojego tekstu przez wy-
odrębnienie w nim części i opatrzenie ich tytułami. Rozdziały tekstu, jak umow-
nie nazywa się tu jednostki hierarchizacji (czyli podziału tekstu), można dowol-
nie przemieszczać, usuwać, wstawiać; także wraz z całymi podporządkowanymi
im drzewami podrozdziałów, punktów i podpunktów. Hierarchia tekstu może
odzwierciedlać nie tylko tradycyjną strukturę tekstu-książki, ale - na przykład -
także historię wymiany korespondencji w pewnej sprawie, dzięki czemu wszystkie
akta mogą się znaleźć w jednej "teczce", czyli pliku dyskowym.
Sposoby tworzenia hierarchii tekstu są łatwe do opanowania, najprościej na
przykładach własnych, rzeczywistych zadań. W szczególności sam tytuł hierarchii
(Hierarchia tekstu) może być zastąpiony innym określeniem, odpowiadającym
zawartości tekstu, na przykład: Listy do N.
Warstwa redagowania tekstu
Zasadnicza praca nad fragmentem tekstu rozpoczyna się po przebyciu dwu warstw
opisanych w poprzednich punktach. Na ekranie pojawiają się początkowe wiersze
wybranego fragmentu tekstu. Jeśli rozpoczynamy pracę nad nowym tekstem, to
centralna część ekranu, przeznaczona na redagowany tekst, jest pusta. Kursor
wskazuje na pierwszy znak tekstu.
W dwu dolnych wierszach ekranu jest stale wyświetlany status edytora. Znaj-
dują się tu m.in. graficznie przedstawione informacje o ustawieniu marginesów
i tabulatorów, jak cównież symbole trybu redagowania bieżącego wiersza: na
przykład, czy przy zmianie wiersza obowiązuje automatyczne dzielenie wyrazów
na sylaby, automatyczne justowanie (czyli wyrównywanie marginesów) infor-
macja o wysokości bieżącego wiersza itp. Dalej są wyświetlane: numer bieżącej
strony i ogólna liczba stron w redagowanym dokumencie, a ściślej, w jego mo-
dule w sensie hierarchii tekstu (nazwa modułu jest wyświetlana w lewym górnym
rogu ekranu), numer rządka na stronie (wysokość wiersza wynosi np. 2 rządki),
liczba rządków na stronie, numer kolumny, w której znajduje się kursor, ilość
wolnej pamięci przeznaczonej do zapamiętywania tekstu, tryb wpisywania tekstu
(wstawianie lub zamienianie liter), a także aktualny czas w godzinach, minutach
i sekundach.
Podkreślmy znaczenie wierszy statusowych edytora. Stanowią one element
komunikacji edytora z użytkownikiem (zob. zad. 8.6).
Podczas redagowania do dyspozycji użytkownika pozostaje klawiatura kom-
putera w funkcji klawiatury zwykłej maszyny do pisania plus kilkadziesiąt dzia-
łań specjalnych, uzyskiwanych za pomocą operacji klawiszowych, służących
8.5. Systemy podpowiedzi
257
m.in. do wybierania ofert (klawisze funkcyjne jFl |, |F2 |, ..., |F8 |, strzałki,
[Enter |, | Ins |). Tytuły ofert są umieszczane w górnym wierszu ekranu.
Przemieszczanie kursora w obrębie tekstu umożliwiają klawisze oznaczone
strzałkami oraz klawisze
PgUp , PgDn
Poza tym użytkownik
może odnajdywać określone fragmenty tekstu i przechodzić do ich redagowania
za pomocą oferty ukazującej się po naciśnięciu klawisza | F6 |.
Operacje klawiszowe wymagają czasami naciśnięcia określonego klawisza z li-
terą po uprzednim naciśnięciu i przytrzymaniu innego klawisza, na przykład
I Ctrl I lub
Alt
Polskie litery, czyli litery ze znakami diakrytycznymi
(takimi jak ogonki), otrzymuje się przez naciśnięcie i przytrzymanie klawisza
| Alt | oraz naciśnięcie klawisza z odpowiednią literą bez znaku diakrytycznego.
Literę "ż" uzyskujemy naciskając klawisze [Alt z|, natomiast do napisania li-
tery "ź" należy użyć klawiszy [Alt XJ. Wielkie litery pisze się przytrzymując
klawisz I Shif 11 lub po naciśnięciu klawisza-przełącznika o nazwie Caps Lock
Przykładowo, sekwencja klawiszy potrzebnych do napisania nazwiska
Stanisław Witkiewicz
wygląda następująco:
Shift S TANISAltLAW
Sp
Shift W ITKIEWICZ
Uzyskanie niektórych znaków - na przykład, pisanie wielkich polskich liter -
wymaga naciśnięcia trzech klawiszy.
Innymi przykładami operacji klawiszowych są: przeskok do następnego (po-
przedniego) wyrazu, uzyskiwany za pomocą strzałek przy przytrzymanym klawi-
szu 1 Ctrl | lub wpisanie twardej spacji, czyli odstępu, który nie jest usuwany
przy automatycznym justowaniu wiersza (wykonywane po naciśnięciu klawiszy
Alt Sp ).
8.5. Użytkowniku, pomóż sobie sam!
Liczba różnych operacji w edytorach tekstów sięga zwykle kilkudziesięciu i prze-
kracza możliwości łatwego ich zapamiętania. Jednak budowa edytorów, podob-
nie jak innych programów usługowych, na ogól umożliwia stopniowe zagłębianie
się i poznawanie ich właściwości poprzez poruszanie się po ścieżkach ofert gru-
pujących operacje. Hierarchiczność ofert (ang.: puli down menu) ułatwia za-
pamiętywanie dróg wyboru operacji przez ich uporządkowanie.
Posłużenie się edytorem do najprostszych zadań nie wymaga jednak dużej
wprawy. Podstawowa wiedza sprowadza się do umiejętności uruchomienia edy-
tora, przejścia w tryb redagowania, wpisania tekstu i ewentualnego skorygowania
17 Elementy informatyki
258
8. Przetwarzanie tekstów
Backspace - rozdz. 2), zapamiętania go w pliku
(stosując klawisze |Del |
i wydrukowania oraz zakończenia pracy z programem.
Edytor TAG ma wbudowane dwa słowniki (ortograficzny i wyrazów blisko-
znacznych) oraz wypisy z zasad ortografii i interpunkcji języka polskiego. Wgląd
w dane słownikowe można uzyskać z oferty | F7 | w warstwie redagowania tekstu.
Wbudowane w edytor bazy słownikowe mogą być rozszerzane przez użytkownika.
Nawet przy intensywnym korzystaniu z edytora nie wszystkich operacji używa
się równie często. Aby użytkownik mógł zorientować się w zasobach możliwości,
edytory są wyposażone w operacje, których wykonanie powoduje wyświetlenie na
ekranie wykazu dostępnych działań wraz z krótkim opisem. Edytor TAG nie ma
specjalnego systemu podpowiedzi. Jednak przeglądnięcie jego ofert i wykazów
(wyświetlanych za pomocą klawiszy funkcyjnych) i lektura zawartych tam uwag
(zob. zad. 8.11) w znacznym stopniu pozwalają orientować się w działaniach edy-
tora. Co więcej, jest to informacja kontekstowa w tym sensie, że opisy działań
nieefektywnych w danej sytuacji są wyświetlane bledszym pismem. Dzięki temu
wiadomo, że dana możliwość istnieje, ale można ją uzyskać w innym kontekście
(na przykład, po wykonaniu innego ciągu działań).
Komputerowe systemy podpowiedzi czy też wbudowane dokumentacje, okre-
ślane w żargonie informatycznym angielską nazwą help, są wyświetlane na ogół
po naciśnięciu klawisza | Fl [. W innych edytorach pomoc jest wyświetlana po
jednoczesnym naciśnięciu klawiszy | Alt H | lub podobnych (zob. zad. 8.7).
i
8.6. Okna i ich zastosowanie
Po naciśnięciu któregoś z klawiszy funkcyjnych edytor TAG wyświetla na ekranie
prostokątne pole z wykazem możliwych do wykonania czynności. Mówimy, że
na ekranie zostało otwarte okno. Użycie okien pozwala - mówiąc obrazowo -
nakładać na już istniejący na ekranie obraz (tekst) inną informację (tekst, obraz)
w sposób nie niszczący poprzednio wyświetlanej informacji (por. zad. 8.8). Do-
konywanie wyborów z niektórych ofert (za pomocą klawiszy | Enter | lub | Ins |)
powoduje otwieranie kolejnych okien. Jako przykład zastosowania okien w edyto-
rze TAG można prześledzić uzyskiwanie podpowiedzi z zakresu ortografii, otwie-
rając w warstwie redagowania okno z odpowiednią informacją za pomocą klawisza
| F7 | i używając następnych klawiszy - zgodnie z wyborem w ofercie. Zamknięcie
okna i przywrócenie poprzedniej zawartości ekranu następuje po naciśnięciu kla-
wisza [Esc |.
Inną zaletą związaną z użyciem okien, niedostępną jednak w edytorze TAG,
jest wykonywany na polecenie użytkownika podział ekranu na części, w których
można wyświetlać nie sąsiadujące ze sobą fragmenty redagowanego pliku, a nawet
informacje z różnych plików. Ta możliwość jest cenna przy montowaniu tekstów
8.7. Manewrowanie kursorem
259
(w tym także tekstów programów) złożonych z wielu oddzielnych modułów (na
przykład procedur lub grup procedur opracowywanych osobno i przechowywa-
nych w osobnych plikach). Z jednym oknem na ekranie może być związanych
wiele plików, tzn. za pomocą prostego przełączenia (najczęściej jest nim operacja
klawiszowa) można w danym oknie oglądać różne pliki. Dowolne porcje tekstu
z plików przyłączonych do różnych okien można wymieniać między plikami. Sy-
stem zakładek umożliwia natychmiastowe przeskoki z kontekstu jednego pliku
do innego, z dokładnością do położenia kursora w tekście. Taki mechanizm wy-
boru i przesyłania tekstów daje użytkownikowi możność korzystania z informacji
tekstowych nagromadzonych w całej pamięci masowej komputera, tzn. przecho-
wywanych w dowolnych plikach na dyskach.
W edytorze TAG funkcje tak rozumianego zarządzania informacją spełniają
opisane uprzednio warstwy wyboru i struktury tekstu wraz z możliwością wy-
syłania wybranych porcji tekstu do odrębnych plików dyskowych i pobierania
informacji z plików.
8.7. Komputerowy "brudnopis",
manewrowanie kursorem
Opracowywanie tekstu na komputerze rzadko kiedy odbywa się "od lewej do pra-
wej", przeciwnie - przedstawia się jako nieustanne ulepszanie zarówno treści jak
i formy tekstu w różnych jego fragmentach. W odróżnieniu od ręcznej "techno-
logii" w komputerze każda wersja tekstu jest czysta: bez skreśleń, widocznych
wstawek, odsyłaczy, zamian itd. Na etapie opracowywania tekstu z pomocą edy-
tora nie trzeba zużywać papieru.
Pisząc tekst na ekranie możemy w każdej chwili przejść do dowolnego jego
miejsca, aby coś zmienić lub poprawić. Miejsce na ekranie, tj. położenie kur-
sora w tekście, zmienia się za pomocą klawiszy oznaczonych strzałkami. Strzałka
wskazująca w górę oznacza przejście do poprzedniego wiersza, strzałka w dół -
przejście do następnego wiersza tekstu (jeśli taki istnieje).
Oprócz możliwości użycia strzałek edytor TAG ma inne operacje manewrujące
kursorem. Podajemy je w przyjętej symbolice łącznego naciskania klawiszy:
- przemieszczanie kursora z dokładnością do pojedynczego słowa:
Ctrl
Ctrl
- manewrowanie kursorem w obrębie wiersza tekstu: End | (przejście na ko-
niec wiersza), | Home | (przejście na początek wiersza);
- przenoszenie kursora na następną stronę ekranu: PgDn
- przenoszenie kursora na poprzednią stronę ekranu: PgUp
- przenoszenie kursora na skraj pliku: Ctrl End (na koniec), Ctrl Home
(na początek);
260
8. Przetwarzanie tekstów
- zmiana aktualnie redagowanego modułu tekstu: Ctrl PgDn (przejście do
następnego modułu w hierarchii tekstu), Ctrl PgUp (przejście do poprze-
dniego modułu); przy tej operacji w lewym górnym rogu ukazuje się auto-
matycznie nazwa nowego modułu (rozdziału, punktu itp.) - moduły reda-
gowanego tekstu można również zmieniać w warstwie hierarchii tekstu (za
pomocą klawiszy: | Esc |, |Esc |, strzałki, |Enter [).
W poruszaniu się po tekście może dopomóc myszka. Niektóre edytory wyświe-
tlają w obramowaniu tekstu na ekranie specjalne symbole (np. małe prostokąciki)
określające położenie pokazywanego na ekranie fragmentu tekstu względem całego
pliku. Ustawienie kursora (za pomocą myszy) na takim symbolu i przeciąganie
go myszką wzdłuż obramowania powoduje szybkie przemieszczanie się w obrębie
całego pliku. W przypadku edytora TAG wędrowanie po tekście za pomocą myszy
wymaga odrywania jej od podłoża po przejściu jednej ekranowej porcji tekstu, co
nie jest wygodne zwłaszcza przy dużych przemieszczeniach; w przeciwnym razie
powrotny ruch myszy po stole spowoduje zmianę kierunku przesuwania tekstu na
ekranie.
Edytory mogą być wyposażone w jeszcze inne operacje przemieszczania kur-
sora w tekście, na przykład przez umożliwianie wstawiania wspomnianych za-
kładek w plikach. Ponadto opisane wyżej typowe przemieszczania kursora mogą
być wykonywane za pomocą innych klawiszy. Oto przykład konsekwentnego
rozwiązania zastosowanego w jednym z edytorów: |End | - powoduje przeniesie-
nie kursora na koniec wiersza, [ End 11 End | - przeniesienie do ostatniego wiersza
na ekranie, [ End 11 End 11 End | - przeniesienie na koniec pliku; klawisz [ Home | jest
używany analogicznie. Jeszcze innym przykładem może być technika przewija-
nia, kiedy kursor pozostaje na ekranie nieruchomy, natomiast wszystkie wiersze
są przesuwane w górę lub w dół (zob. zad. 8.9).
8.8. Usuwanie i wstawianie tekstu
Edytor TAG - jak każdy inny tego typu program - podczas redagowania tekstu
może pracować w jednym z dwu trybów: wstawiania lub zastępowania znaków.
W trybie wstawiania znak wpisywany w pozycji kursora powoduje przesunięcie
wszystkich znaków występujących w wierszu na prawo od niego o jedną pozycję
w prawo. W trybie zastępowania nowy znak zastępuje w miejscu wskazywa-
nym przez kursor znak, który znajdował się tam uprzednio. Przełączenie między
obydwoma trybami pracy uzyskuje się za pomocą klawisza | Ins |. Pamiętamy, że
klawisz | Ins | w edytorze TAG jest też używany w roli klawisza akceptacji, podob-
nie jak klawisz JEnter |. Informacja o aktualnym trybie pracy jest wyświetlana
w wierszu statusowym.
8.8. Usuwanie i wstawianie tekstu
261
Pojedyncze znaki leżące na lewo od kursora można usuwać za pomocą klawisza
Backspace , a naciśnięcie klawisza |Del | powoduje usunięcie znaku wskazywa-
nego przez kursor. Ponadto specjalne operacje pozwalają usuwać:
Ctrl Del - część słowa na prawo od kursora,
Ctrl Backspace - część słowa na lewo od kursora,
Ctrl Ins cały wiersz, w którym znajduje się kursor.
Przez naciskanie klawisza | Enter | w pozycji pierwszej kolumny zyskuje się
dodatkowe puste wiersze. Użycie w tej kolumnie klawisza Backspace powo-
duje natomiast złączenie wierszy tekstu ze sobą (efekt jest widoczny dopiero po
przejściu z kursorem do sąsiedniego wiersza). Większe jednostki tekstu można
usuwać lub wstawiać za pomocą omówionych dalej operacji blokowych.______
Jako ciekawostkę edytora TAG można podać operację Ctrl szara gwiazdka
(prawy moduł klawiatury), która zamienia miejscami dwa sąsiednie znaki i może
służyć do szybkiego poprawiania tego rodzaju błędów.
Przykład 8.1. Załóżmy, że szukając dobrego początku wypracowania na temat
współoddziaływania techniki i sztuki napisaliśmy na ekranie te słowa (darujmy so-
bie w tym miejscu i w następnych ocenę wartości cytatu, jesteśmy zainteresowani
obserwowaniem jego ewolucji przy użyciu edytora):
Poczucie piękna i formy ornamentuje wytwory
technicznej myśli ludzkiej._
Podkreślenie oznacza położenie końcowe kursora. Zaraz potem - jak to przy
wypracowaniach bywa - popadliśmy w zadumę, w efekcie której postanowiliśmy
wzbogacić orzeczenie okolicznikiem. Aby wstawić nowy wyraz, wykonujemy
następujący ciąg operacji: strzałka w górę (kursor w górę), | Ins | (przejście do
trybu wstawiania, potrzebne tylko wtedy, jeśli obowiązywał tryb zastępowania
znaków), subtelnie (litery wstawianego wyrazu), strzałka w dół (kursor w dół),
JEnd | (kursor na koniec wiersza) i (ewentualnie) | Ins |. Początek wypracowania
brzmi obecnie:
Poczucie piękna i formy subtelnie ornamentuje wytwory
technicznej myśli ludzkiej._
Teraz przestaje się nam podobać przydawka "ludzkiej". Zamieniamy ją na
inną, naciskając po prostu 9 razy klawisz |Del | i wpisując: człowieka. Nowa
wersja brzmi:
Poczucie piękna i formy subtelnie ornamentuje wytwory
technicznej myśli człowieka.-
262
8. Przetwarzanie tekstów
Za chwilę ten sam los spotyka wytwory. Operacje: strzałka w górę, | Ctrl
I End I
Ctrl->
Ins
"produkty":
produkty | Ins |, strzałka w dół,
Home
zmieniają je na
Poczucie piękna i formy subtelnie ornamentuje produkty
technicznej myśli człowieka..
Spoglądamy jeszcze przez chwilę krytycznym okiem i, jak to się często zdarza,
całość wędruje do kosza: Ctrl Ins[, Ctrl Ins]. Po czym - robiąc jeszcze lep-
szy początek! - wpisujemy z przekonaniem:
Produkty cywilizacji technicznej niepostrzeżenie
kształtują odczucia sfery ducha._
W ten sposób powoli wyłania się tekst wypracowania.
8.9. Operacje na blokach tekstu
W edytorze TAG blok tekstu określa się po wejściu w tryb działań na blokach
(klawisz | F5 |). Od tej chwili manipulacje kursorem będą powodowały zaznacza-
nie bloku (zaznaczony fragment tekstu przybiera inny odcień na ekranie). Kursor
można przesuwać znak po znaku, wiersz po wierszu, lecz również można zaznaczyć
jako blok większy fragment, na przykład przez przejście na koniec redagowanego
modułu tekstu (naciskając klawisze Ctrl End|). Za zakończenie oznaczania gra-
nic bloku jest przyjmowane w edytorze TAG powtórne naciśnięcie klawisza |F5 |.
Na ekranie ukazuje się wtedy okienko z odpowiednią ofertą.
Z blokami tekstu można postępować tak jak z pojedynczymi znakami (wsta-
wiać, kasować, przemieszczać) oraz podobnie jak z plikami - sprowadzać z dysku
do pamięci roboczej edytora i wysyłać na dysk. Usuwany z tekstu blok jest prze-
chowywany w buforze pamięci zakładanym automatycznie przez edytor, skąd
można go na życzenie odzyskać - na przykład, by wstawić później w inne miej-
sce. Należy jednak pamiętać, że posłanie innego bloku do bufora powoduje utratę
poprzedniej zawartości bufora.
Jednym z celów zaznaczania bloku może być chęć wykonania wybranej ope-
racji na całym fragmencie tekstu zawartym w bloku. W szczególności blokiem
można uczynić cały moduł. Blok można w całości formatować, czyli automa-
tycznie zmienić szerokość i wysokość wierszy oraz marginesów, justować (oferta
F3 |) lub automatycznie łączyć wszystkie akapity w bloku w jeden akapit. (Roz-
poczęcie pisania tekstu od nowego akapitu uzyskuje się przez naciśnięcie klawisza
| Enter | - pisząc tekst nie naciska się klawisza | Enter | na końcu każdego wier-
sza, gdyż podczas pisania przejście do nowego wiersza następuje automatycznie.)
8.9. Operacje na blokach tekstu
263
Można również automatycznie zmienić w bloku krój i atrybuty pisma (korzy-
stając z ofert | Fl |, | F2 | wybieranych przy oznaczonym bloku). Szczegółowy
wykaz operacji na blokach ukazuje się za każdym razem na ekranie monitora.
Warto zwrócić uwagę na kontekstowe działanie oferty działań na blokach. Po
jednorazowym naciśnięciu klawisza | F5 | i oznaczeniu bloku, kolejne naciśnięcie
klawisza | F5 | powoduje wyświetlenie innej oferty, niż dwukrotne naciśnięcie kla-
wisza | F5 | bezpośrednio po sobie i bez zaznaczenia bloku w redagowanym tekście.
W pierwszym wypadku z oferty można wybrać m.in. przechowanie bloku w pa-
mięci lub wysłanie go na dysk, a w drugim - wstawienie bloku ostatnio prze-
chowywanego w buforze lub sprowadzenie tekstu z pliku dyskowego. Przy okazji
takich transferów bloków z tekstami można wykonać konwersję danych przyj-
mując jeden z popularnych standardów kodów liter polskich: Mazovia lub Latin
II - albo przesłać plik bez konwersji (czyli w standardzie kodu ASCII). Ostatnia
możliwość jest szczególnie pożyteczna w przypadku pisania za pomocą edytora
TAG programów i danych dla programów.
Operacje plikowe na blokach umożliwiają podział redagowanego dokumentu
na części lub odwrotnie - jego składanie z różnych fragmentów zapamiętanych
w być może różnych kartotekach.
Możliwość wymiany informacji między plikami rozszerza koncepcję modułów
tekstu definiowanych w warstwie hierarchii tekstu i pozwala na dysponowanie
tekstami bez konieczności zakończenia pracy z edytorem. Działania takie mogą
być szczególnie przydatne przy budowaniu większych programów, których po-
szczególne fragmenty są przechowywane w osobnych plikach.
Operacje na blokach stanowią ważne i silne narzędzie w rękach użytkownika
edytora tekstu. Umiejętność posługiwania się nimi należy zaliczyć do podstawo-
wych. Nie warto więc odkładać nauczenia się ich na potem.
Przykład 8.2. Pamiętamy, że w poszukiwaniach dobrego początku dla naszego
przykładowego wypracowania jego pierwsze zdanie przybrało ostatnio postać:
Produkty cywilizacji technicznej niepostrzeżenie
kształtują odczucia sfery ducha._
Kontynuując przeobrażenia tekstu, dokonujemy następujących zabiegów:
| Home J - kursor na początek wiersza,
- kursor o jedno słowo w prawo,
- przejście w tryb operacji blokowych,
- oznaczenie bloku odczucia sfery ducha,
- skasowanie oznaczonego bloku tekstu z jednoczesnym
przeniesieniem go do bufora,
- kursor na początek ekranu,
Ctrl ->? |
manewry strzałkami
Ctrl Home
264
8. Przetwarzanie tekstów
|F5|IF5
I~fT|
- przejście w tryb operacji odczytywania bloków,
- wstawienie bloku pamiętanego w buforze, którym
tutaj jest tekst odczucia sfery ducha, w miejsce
wskazywane przez kursor, czyli na początek zdania.
Dalej zamieniamy o na początku bloku na 0, zamieniamy P na p, oznaczamy
jako blok napis produkty cywilizacji technicznej i przemieszczamy go na
koniec zdania. Otrzymujemy w rezultacie zdanie:
Odczucia sfery ducha niepostrzeżenie
kształtują produkty cywilizacji technicznej..
- obiecujący punkt wyjścia do dalszych zmagań z tekstem. ?
8.10. Wyszukiwanie i zamiana tekstów
Edytor TAG, podobnie jak inne programy o tym przeznaczeniu, umożliwia re-
dagowanie systematyczne, czyli automatyzację zmian o cechach regularnych oraz
powtarzających się w tekście. Jako przykład możemy rozważyć zadanie zmiany
pewnej nazwy występującej wielokrotnie w całym tekście. Dla ustalenia uwagi
przyjmijmy, że chodzi o zastąpienie napisu wiek XX napisem wiek XXI na 20 stro-
nach tekstu. Przejrzenie tak znacznej ilości tekstu wiersz po wierszu za pomocą
komputera bywa nie mniej uciążliwe niż tradycyjne wertowanie kartek. Przy ta-
kich okazjach daje znać o sobie ujemna strona wycinkowosci tekstu widocznego
jednorazowo na ekranie, czyli widzenie tunelowe. To i podobne zadania można
wykonać szybko za pomocą operacji szukania i zastępowania - w edytorze TAG
operacje tego rodzaju są zgrupowane w ofercie otwieranej naciśnięciem klawisza
[~|
W następstwie otrzymujemy wykaz możliwości, a wśród nich wyszukiwanie
).
F2
Naci-
napisów (|F11) lub wyszukiwanie połączone z zastępowaniem (
skamy więc klawisz | F2 | i otrzymujemy zaproszenie do napisania poszukiwanej
frazy. Wprowadzamy z klawiatury napis iek XX. Następnie musimy podać tekst
zastępujący oraz zdecydować czy podczas szukania mają być utożsamiane wiel-
kie i małe litery, czy też nie. Kolejne zamiany w tekście mogą podlegać kontroli
ze strony użytkownika (klawisze |Enter | lub | F3 |) albo dokonywać się auto-
matycznie (|Fl |). W naszym przypadku wpisujemy tekst iek XXI i wybieramy
kontrolę indywidualną, przy której każdą zamianę tekstu musimy zakceptować
- naciskamy wtedy klawisz |Enter |, jeśli należy spowodować zamianę w danym
miejscu, lub klawisz |F3 |, gdy odnaleziony kontekst powinienien być pozosta-
wiony bez zmian. Po takim przetworzeniu tekstu możemy być pewni, że wszystkie
wystąpienia napisu wiek XX zostały zamienione na wiek XXI.
8.11. Wycofywanie pochopnych decyzji
265
Przykładem sytuacji, w której zautomatyzowanie zamiany mogłoby doprowa-
dzić do powstania błędów, jest zamiana nazw w programie wykonana bez dozoru
użytkownika. Edytor nie odróżnia nazw zmiennych i procedur od ewentualnych
tych samych nazw (np. spójników "i") użytych w komentarzach. W takich wy-
padkach korzystamy z możliwości decydowania o każdej zamianie w zależności od
kontekstu.
Inną operacją systematycznego redagowania tekstu w edytorze TAG jest mo-
żliwość półautomatycznej korekty ortograficznej. Działanie to wybiera się z oferty
|F7 I jako czynność |F2 |. Odnajdywanie w tekście cząstek wyrazów podejrzanych
o błąd wskutek ich braku w słowniku edytora wymaga również określenia, ile razy
ma być automatycznie powtórzone przez edytor - tę krotność wpisujemy w od-
powiedzi na dodatkowe pytanie edytora. Po wykonaniu pierwszego przeszukania
kolejne poszukiwania są wykonywane za pomocą klawisza |Enter |, co pozwala
pominąć miejsca, w których błąd w istocie nie występuje. Przy okazji tych poszu-
kiwań można dołączać do słownika nowe wyrazy, eliminując w ten sposób dalsze
ich kwestionowanie. Korekta odnalezionego błędu polega na ręcznym zastąpieniu
wyrazu jego poprawną wersją.
Zarówno operacja szukania łańcucha znaków z zastępowaniem jak i samego
szukania są łatwe do nadzorowania dzięki bezpośredniej konwersacji z edytorem.
Samodzielnie wykonane ćwiczenie z tekstem wyjaśnia tu więcej niż szczegółowy
opis.
Długość łańcucha znaków określanego przy przeszukiwaniach jest na ogół
ograniczona i nie może przekraczać kilkudziesięciu znaków (20 znaków w przy-
padku edytora TAG).
8.11. Wycofywanie pochopnych decyzji
Tytułowe zagadnienie jest jedną z cech przyjaznego oprogramowania powszech-
nego użytku. Przy redagowaniu tekstów daje czasami znać o sobie pośpiech. Oto
skasowaliśmy bezwiednie o kilka znaków więcej, niż było potrzeba. To błahostka,
nieco gorzej przedstawia się sprawa, gdy niebacznie wypadnie nam z tekstu cały
wiersz. A co zrobić, gdy po wielu przeróbkach dochodzimy do wniosku, że naj-
lepiej byłoby... powrócić do stanu początkowego pliku?! Na tego rodzaju oko-
liczności edytory przewidują operacje odwoływania niektórych (lub wszystkich)
wykonanych czynności.
Operacja, o którą tutaj chodzi, nazywa się w oryginale angielskim undo i po-
zwala na anulowanie pojedynczych operacji, w tym także blokowych, a nawet ich
ciągu. Niezależnie od złożoności operacji, tzn. czy dotyczyły pojedynczego znaku,
przesunięcia kursora o jedno pole czy działania na całym bloku, edytory z dobrze
zaprojetowanym anulowaniem działań po naciśnięciu jednego klawisza (zawsze
266
8. Przetwarzanie tekstów
tego samego) powodują cofanie "komputerowej historii" w odniesieniu do reda-
gowanego tekstu. Użytkownik edytora, dysponujący taką operacją "przywraca-
nia" przeszłości, nabiera zupełnie innych przyzwyczajeń (nie zawsze najlepszych
z punktu widzenia edytorów bez takich środków) - ma większą swobodę stawia-
nia nie do końca przemyślanych kroków, bo zawsze może je odwołać. Operacja
ta, poza celami ratunkowymi, może być również stosowana do realizowania za-
mierzonych działań, na przykład do szybkiego obejrzenia tekstu w innym miejscu
pliku i automatycznego powrotu do punktu wyjścia.
8.12. Składowanie informacji
Koncentrując uwagę nad tekstem wypracowania lub programu można zapomnieć
o bardzo ważnej zasadzie okresowego składowania informacji, czyli zapamię-
tywania w pamięci trwałej (na dysku lub taśmie magnetycznej) przejściowych
stanów pliku zawierającego opracowywany tekst. Pamiętanie o wykonywaniu
składowania informacji niektóre edytory biorą na siebie: jednym z rozwiązań jest
określenie przez użytkownika przedziału czasu między kolejnymi składowaniami.
Zasada taka jest stosowana m.in. w edytorze TAG. Poza tym użytkownik w wy-
branych przez siebie chwilach może zawsze wykonać składowanie bieżącego stanu
redagowanego tekstu. W edytorze TAG do wykonania składowania służy operacja
| F8 1 umieszczona w ofercie wywoływanej klawiszem [ F8 |. Wystarczy zatem w do-
wolnej chwili (także w warstwie redagowania hierarchii tekstu) nacisnąć dwukrot-
nie klawisz funkcyjny |F8 |, aby mieć pewność, że bieżąca postać zostanie utrwa-
lona w pamięci dyskowej. Dodatkowo edytor sam w określonych odstępach czasu
wykonuje automatycznie składowanie w osobnym pliku, któremu, dla odróżnienia
od pliku zapisywanego przez użytkownika, nadaje rozszerzenie BAK.
Pamiętajmy, aby przy pracy nad tekstem za pomocą komputera nie narażać
się na przypadkową - na przykład z powodu zaniku napięcia w sieci lub zablo-
kowania programu - utratę efektów tej pracy. Od początku warto wyrobić sobie
nawyk wykonywania składowania co pewien czas, na przykład co 10 minut, nie
zważając na automatyczne składowania wykonywane okresowo przez sam edytor.
8.13. Przeglądanie plików
W poszukiwaniach dobrego początku dla nowego tekstu mogą okazać się przy-
datne nasze doświadczenia i wyniki uzyskane przy pisaniu innych tekstów. Za-
kładając, że przechowujemy je w plikach na dysku, możemy za pomocą edytora
TAG szybko je przeglądnąć. W tym celu stosujemy operację | F8 [ |~F8~|, która
poleca zapamiętać na dysku redagowany plik, po czym przechodzimy do warstwy
wyboru pliku ([ Esc | |Esc |...) i wprowadzamy do pamięci edytora interesujące
8.14. Zakończenie pracy
267
nas dane, postępując podobnie jak to ma miejsce w popularnych programach
pośredniczących w wykonywaniu zleceń systemu operacyjnego. Edytor TAG sta-
nowi tu przykład programu tworzącego środowisko szersze niż na potrzeby re-
dagowania pojedynczego pliku. Wykazy i zawartości plików można oglądać bez
konieczności kończenia sesji redagowania. Przypomnijmy, że dla uwidocznienia
plików o rozszerzeniach innych niż TAG, należy uprzednio zmienić na *. * szablon
wyświetlanych nazw plików w górnym segmencie okna warstwy wyboru (klawisz
[Tab |).
Przechodzenie w górę drzewa katalogów odbywa się przez zaakceptowanie
wiersza z wpisem ". .". Wejście do katalogu o nazwie podanej na wykazie nastę-
puje po wybraniu nazwy katalogu kursorem i naciśnięciu klawisza | Enter | lub
llnsl.
8.14. Zakończenie pracy
Pracę z edytorem można zakończyć dwoma sposobami: z zapamiętaniem wy-
ników redagowania, czyli tekstu ze wszystkimi naniesionymi w nim zmianami,
albo z zaniechaniem zapamiętania zmienionego tekstu.
W edytorze TAG do planowego zakończenia pracy z zachowaniem wszyst-
kich wniesionych do pliku modyfikacji służy operacja | Fl | w ofercie |F8 | (tzn.
naciskamy klawisz funkcyjny JF8 |, a po nim | Fl |). Operacja ta powoduje za-
pamiętanie na dysku aktualnej wersji redagowanego tekstu i przejście do zewnę-
trznej warstwy edytora. Zatem do całkowitego zakończenia pracy z programem
trzeba tę operację powtórzyć dwukrotnie lub trzykrotnie w zależności od miej-
sca aktualnego pobytu w edytorze. Innym - manualnie prostszym sposobem
zakończenia redagowania z zachowaniem wykonanych zmian jest wielokrotne na-
ciskanie klawisza |Esc | (po dwa naciśnięcia na opuszczenie jednej warstwy edy-
tora).
Do zaniechania prac nad tekstem i przywrócenia jego stanu początkowego,
czyli odstąpienia od pamiętania jakichkolwiek zmian wprowadzonych do pliku,
służy w edytorze TAG operacja |F2 [, również wybierana z oferty |F8 |. Rezygna-
cja także i tym wypadku oznacza powrót do warstwy poprzedniej, toteż należy
ją ewentualnie powtórzyć w zewnętrznej warstwie edytora.
Rezygnacja z redagowania, a ogólnie zaniechanie jakiejś czynności lub zakoń-
czenie pracy, bywa oznaczana w programach literą Q (lecz nie w edytorze TAG).
Jest to drugie (obok funkcji klawisza |Esc |) ważne z praktycznych powodów
standardowe zakończenie korzystania z programów usługowych komputerów oso-
bistych.
Edytory, w przypadku zapamiętania zmodyfikowanego pliku, na wszelki wy-
padek przechowują na dysku często również wersję pliku sprzed edycji, nadając
268
8. Przetwarzanie tekstów
jej rozszerzenie BAK. Jeśli chcemy szczególnie chronić początkową zawartość wy-
branych plików, powinniśmy przed rozpoczęciem edycji skopiować je w osobne
miejsce na dysku, gdyż nie wszystkie edytory zapamiętują faktyczny początkowy
stan pliku, ograniczając się do pamiętania stanu po ostatnim składowaniu.
Przykład 8.3. Po wykonaniu poprawek w pliku o nazwie BAJKA-24. TAG i zakoń-
czeniu sesji z edytorem za pomocą zwielokrotnionej operacji |Esc | w kartotece
zostaną zapisane dwa pliki:
BAJKA-24.TAG - zawierający wszystkie poprawki i zmiany,
BAJKA-24. BAK - zawierający poprzednią wersję pliku.
Zaniechanie sesji za pomocą operacji | F8 |
BAJKA-24.TAG w niezmienionej postaci.
| F2 |... spowoduje zachowanie pliku
8.15. Inne własności edytorów
Edytory tekstów ogólnego przeznaczenia, w odróżnieniu od edytorów tekstów
programów, wykonują operacje na całych akapitach. Do akapitu, jako do pew-
nej całości, odnoszą się: formatowanie, zmiana kroju pisma, przemieszczanie itp.
Przy posługiwaniu się edytorami działającymi na akapitach nie używa się klawisza
| Enter | na końcu wierszy. Łamanie tekstu w wierszach następuje automatycz-
nie, a w wypadku edytora TAG może temu dodatkowo towarzyszyć automatyczne
dzielenie wyrazów.
Inną szczególną ofertą edytorów (dostępną także w edytorze TAG) jest możli-
wość rysowania ramek. Stosuje się różne techniki: ramkę mqżna utworzyć ze
znaków z rozszerzonego kodu ASCII lub kreśląc za pomocą kursora (TAG).
Edytory, podobnie jak inne rozbudowane programy, mogą być konfiguro-
wane. Pozwala to użytkownikowi ustalać pewne preferencje, na przykład kolory
na ekranie, odstępy czasu między kolejnymi składowaniami itp. Taką możliwość
ma również edytor TAG od drugiej wersji począwszy.
Komputerowe redagowanie tekstów jest bardzo elastyczne. Niemniej, przygo-
towanie wypracowania z pomocą komputera również wymaga pewnego nakładu
pracy. W pewnych sytuacjach, gdy dzisiejsze wypracowanie może się jutro okazać
cenne jako artykuł na łamy gazetki szkolnej - w związku z czym wypadnie zmienić
mu format kolumn i krój pisma - komputerowe edytory okazuj ą się niezastąpione.
W niektórych edytorach kroje pisma mogą być definiowane przez samego u-
żytkownika. Inną cechą przydatną w cyzelowaniu tekstów jest druk propor-
cjonalny, czyli kształtowanie liter na podobieństwo składu drukarskiego - li-
tera "i" jest węższa niż "m" itp. Z kolei użyteczną w pewnych zastosowaniach
własnością edytorów może być makrodefiniowanie operacji klawiszowych,
czyli możliwość ujmowania wspólną nazwą ciągów uderzeń w klawisze tak, by za-
Zadania
269
miast za każdym razem wystukiwać litera po literze te same, często powtarzające
się wyrazy, wzory, dane bibliograficzne lub inne fragmenty tekstu powodować ich
"samopisanie się" poprzez wypisanie krótkiej nazwy (makrowywołania). Rolę
makrowywołań można przyrównać do znaczenia procedur w językach programo-
wania.
Dodajmy jeszcze, że z obecności w niektórych edytorach korektora ortogra-
ficznego (np. w edytorze TAG) nie trzeba wyprowadzać pochopnych przewidywań
o zmierzchu przydatności zasad i wyczucia ortografii wynoszonych ze szkoły.
Wszystkie wspomniane sprawy wiążą się ze specjalizowanymi zastosowaniami
programów redagowania tekstów, wszelako ogólne cechy tych programów są po-
dobne do opisanego tutaj edytora.
Z pomocą komputerów wyposażonych w systemy przetwarzania tekstów pro-
wadzi się doraźną korespondencję, notatki, również administruje pisaniem listów
(z częściową automatyzacją samej zawartości listów włącznie), opracowuje się
raporty, artykuły. Komputery pozwalają przygotowywać całe książki.
Redagowanie tekstów, noszące w międzynarodowej literaturze fachowej miano
word processing, jest dominującym, lecz nie jedynym zastosowaniem komputerów
związanym z przetwarzaniem tekstów. Można oczekiwać, iż niedługo nie będzie
licealisty, który by nie opanował posługiwania sie jakimś edytorem tekstów, tak
jak nie było dawniej gimnazjalisty nie znającego sztuki kaligrafii.
Zadania
8.1. Weź dowolny podręcznik i przyjrzyj się jego układowi oraz opracowaniu tech-
nicznemu, tzn. takim jego cechom, jak podział na rozdziały i mniejsze jednostki,
zastosowane kroje liter, sposoby wydzielania akapitów, opisy rysunków, postać
spisu treści itp. Spróbuj wyodrębnić i nazwać jak najwięcej tego rodzaju cech.
Jeżeli w bibliotece, do której masz dostęp, znajdują się opracowania omawiające
techniczne redagowanie książek (np. Encyklopedia wiedzy o książce, Ossolineum,
Wrocław 1971), przejrzyj je, po czym spróbuj odnaleźć opisy i nazwy tych ele-
mentów, które najbardziej wpływają na wygląd książki (tekstu).
8.2. Zastosuj swoje obserwacje z zadania 8.1 do analizy tekstów innych niż
książki, na przykład gazet, wydawnictw okresowych, instrukcji obsługi urządzeń
domowych, korespondencji urzędowej.
8.3. Obejrzyj teksty kilku programów z tego podręcznika. Wymień regularności
w ich budowie, które spostrzeżesz.
8.4. Zapewne przeglądasz nieraz popularne czasopisma informatyczne czy po pro-
stu gazety. Wskaż wśród zamieszczanych tam ogłoszeń kilka takich, które zostały
270
8. Przetwarzanie tekstów
przygotowane za pomocą prostych edytorów tekstu. Popatrz od strony kompu-
terowej techniki składu na pisemko reklamowe, które właśnie podrzucono Ci pod
drzwi.
8.5. Prostym, lecz bardzo przydatnym zastosowaniem komputera do opracowy-
wania tekstów jest przygotowanie i drukowanie etykiet z adresami, przeznaczo-
nych do umieszczania na przesyłkach. Znajdź inne tego typu przykłady prostych
zastosowań.
8.6. Uruchom jakiś edytor tekstów na swoim komputerze (na komputerach IBM
PC oprócz edytora TAG można często spotkać inne edytory, np. edytor ChiWri-
ter) i przeanalizuj informacje wyświetlane w jego wierszu statusowym.
8.7. Sprawdź, czy wśród informacji wyświetlanych w wierszu statusowym Two-
jego edytora (por. zad. 8.6) znajduje się wskazówka o sposobie korzystania z kom-
puterowego systemu podpowiedzi. Jeśli tak, to postąp zgodnie z nią i zapoznaj
się z wyświetlanymi objaśnieniami.
8.8. Informacja znikająca z ekranu w momencie otworzenia na nim okna pojawia
się z powrotem z chwilą usunięcia (zamknięcia) okna z ekranu. Objaśnij mecha-
nizm programowej realizacji okien, jeśli się go domyślasz.
8.9. Przećwicz dostępne w Twoim edytorze operacje manewrowania kursorem.
Czy używany przez Ciebie edytor umożliwia automatyczne przenoszenie kursora
nad większymi jednostkami leksykalnymi (słowami, wierszami, akapitami)?
8.10. Korzystając z możliwości oznaczania i kopiowania bloków tekstu, wyko-
naj za pomocą edytora zadanie przygotowania 50 zaproszeń. Porównaj ten styl
działania z osiągnięciem podobnego celu za pomocą napisania programu (por.
rozdz. 4).
8.11. Za pomocą edytora TAG wykonaj diagram lub hierarchiczny spis wszy-
stkich ofert edytora TAG, umieszczając przy symbolach klawiszy funkcyjnych
własne zwięzłe objaśnienia ich działania. Opracuj diagram stopniowo, poczy-
nając od tych działań, które spotykasz najczęściej.
9. ŁATWE I SPRAWNE ZARZĄDZANIE
FIRMĄ - ARKUSZ KALKULACYJNY
Arkusz kalkulacyjny jest drugim - po edytorze tekstów - najpopularniejszym pro-
gramem wykorzystywanym przez użytkowników komputerów. "Program, który
pchnął Amerykę w objęcia komputerów osobistych" - już to określenie suge-
ruje, że jest on jedną z najbardziej pomysłowych i zarazem prostych koncepcji
programowania użytkowego. Poniżej przedstawiamy ogólną ideę tego programu.
Następnie zapoznamy się bliżej z jego realizacją o nazwie Quattro Pro, rozpo-
wszechnioną na komputerach IBM PC, pracujących pod kontrolą systemu opera-
cyjnego MS-DOS. Na koniec omawiamy wybrane obszary zastosowań programu,
zarówno klasyczne - ekonomię i handel, jak i nowe - modelowanie i rozwiązywanie
problemów, m.in. w matematyce.
Jak usprawnić żmudne obliczenia? Czym zastąpić papier, ołówek,
gumkę i kalkulator?
Takie pytania zadał sobie w 1978 roku student uniwersytetu w Harvardzie
(USA), zirytowany faktem, że zajmując się problemami z ekonomii, wymaga-
jącymi wykonywania rutynowych działań arytmetycznych, więcej czasu zużywa
na żmudne i nieskomplikowane obliczenia niż na efektywne rozwiązanie samego
problemu. Zaprojektował i skonstruował więc program nazwany później arku-
szem kalkulacyjnym (ang. spreadsheet). Arkusz kalkulacyjny jest typowym
programem usługowym, który po uruchomieniu zamienia komputer w gotowe
do obsługi narzędzie dla użytkownika. Omówiony w poprzednim rozdziale edy-
tor tekstów jest programem, przeobrażającym komputer w niezwykle wygodną
maszynę do pisania, pełniącą w dodatku funkcje zecera, archiwisty, a nawet kon-
sultanta językowego. Porównanie edytora tekstów z maszyną do pisania wypada
mniej więcej podobnie jak porównanie arkusza kalkulacyjnego z tradycyjnymi
narzędziami: kartką kratkowanego papieru, ołówkiem i kalkulatorem.
272
9. Arkusz kalkulacyjny
Arkusz kalkulacyjny pozwala na bezpośrednie zapisywanie na ekranie moni-
tora wzorów, według których są wykonywane obliczenia, na bieżąco wyświetlając
na tym samym ekranie wyniki otrzymane dla konkretnych danych metodą wpi-
saną w arkusz. Zmiana wartości jednej z danych powoduje automatyczne prze-
liczenie wszystkich zależnych od niej wielkości. Te dwie cechy odróżniają korzy-
stanie z arkusza kalkulacyjnego od tradycyjnego podejścia - napisania programu
w języku programowania.
9.1. Co to właściwie jest arkusz kalkulacyjny?
Odpowiedź na to pytanie uzyskamy analizując kilka prostych przykładów. Je-
den z nich jest przedstawiony na rys. 9.1. Widać na nim obraz ekranu moni-
tora podzielony na wiersze i kolumny tworzące umowny arkusz, tak jak pionowe
i poziome linie tworzą zwykły arkusz papieru kancelaryjnego. Jeśli poprowa-
dzimy linie oddzielające wiersze i kolumny, to dokonamy podziału ekranu na
małe prostokątne fragmenty zwane komórkami. Wiersze są oznaczane zwykle
kolejnymi liczbami naturalnymi (1, 2,...), a kolumny - literami alfabetu (A,
B,...). Umożliwia to łatwe odwoływanie się do komórek, np. Al jest adresem
(współrzędnymi) komórki w lewym górnym rogu ekranu (kolumna A, wiersz
1). Każda komórka może zawierać liczbę, wzór, czyli wyrażenie arytmetyczne
(zwany również formułą) lub dowolny ciąg znaków, który będziemy nazywać
napisem.
ABC
1
Przykład
pierwszy
2
3
Lp.
4
1
25
5
2
31
6
3
50
7
8
Suma
106
9
10
Rys. 9.1. Arkusz kalkulacyjny - obliczanie sumy liczb
W powyższym przykładzie zawartością komórki Al jest napis (komentarz)
Przykład pierwszy. Napisami są również Lp. (komórka A3),---------(B7) oraz
Suma (A8). Mówiąc ogólnie, napis jest ciągiem znaków nie analizowanych przez
program, służących jako komentarz lub nagłówek. Wiersze czwarty, piąty i szósty
9.1. CO TO JEST ARKUSZ KALKULACYJNY?
273
zawierają liczby. W komórce B8 jest umieszczone wyrażenie arytmetyczne, obli-
czające sumę liczb z komórek B4, B5 i B6. Na ekranie widzimy tę obliczoną sumę
równą 106 (za chwilę wyjaśnimy, jak obejrzeć samo wyrażenie).
Czy nie jest to jednak zbyt niewygodne? Skoro suma liczb 25, 31 i 50 wy-
nosi 106, czy nie można by wpisać tej liczby do komórki B8, zamiast definiować
wyrażenie, obliczające tak prostą sumę? Za przyjętym rozwiązaniem przemawia
jego uniwersalność. Łatwo bowiem odpowiedzieć na przykład na pytanie, jak
zmieni się ta suma, jeśli 25 zastąpimy liczbą 1142. W przyjętym rozwiązaniu, po
wprowadzeniu zmienionej wartości, nowa suma zostanie automatycznie obliczona
i wyświetlona.
Wspomniane wyrażenie pełni rolę kalkulatora wyświetlającego wynik w ko-
mórce, w której je umieszczono. Każda komórka może mieć swój własny "kal-
kulator" ; innymi słowy w każdej komórce można zapisać odpowiednie wyrażenie.
Na ekranie możemy oglądać zarówno wartości wyrażeń, jak i same wzory umie-
szczone w szablonie arkusza.
Szablonem posługujemy się najczęściej podczas konstruowania i modyfiko-
wania arkusza, a gdy szablon jest już gotowy, interesujemy się bieżącą jego za-
wartością. Na rysunku 9.2 jest przedstawiony szablon arkusza, którego zawartość
jest pokazana na rysunku 9.1.
1
Przykład
pierwszy
2
3
Lp.
4
1
25
5
2
31
6
3
50
7
8
Suma
@SUM(B4..B6)
9
10
Rys. 9.2. Szablon arkusza kalkulacyjnego - obliczanie sumy liczb
Wyrażenie w komórce B8 mogłoby mieć postać B4+B5+B6. W dalszej części
rozdziału wyjaśnimy zalety zapisu SUM(B4. .B6), polecającego obliczyć sumę
liczb umieszczonych w komórkach od B4 do B6 włącznie. Na koniec zmodyfikujmy
arkusz tak, aby obliczał również średnią arytmetyczną liczb. Jednym z rozwiązań
jest umieszczenie w komórce A9 napisu-komentarza Średnia, a w komórce B9
- wyrażenia @SUM(B4. .B6)/3 (znak / oznacza tutaj operację dzielenia). Inne
rozwiązanie jest pokazane na rysunku 9.3.
18 Elementy informatyki
274
9. Arkusz kalkulacyjny
1
Przykład
drugi
2
3
Lp.
4
1
25
5
2
31
6
3
50
7
8
Suma
0SUMCB4..B6)
9
Średnia
+B8/3
10
Rys. 9.3. Szablon arkusza kalkulacyjnego - obliczanie sumy i średniej liczb
9.2. Rozpoczynamy pracę
Wiemy już, co to jest arkusz kalkulacyjny: "elektroniczny papier w kratkę",
na którym można utworzyć dowolny formularz, zawierający w poszczególnych
kratkach-komórkach napisy, liczby i wyrażenia, zgodnie z którymi są wykony-
wane obliczenia. Aby rozpocząć pracę nad własnym szablonem, należy przede
wszystkim wiedzieć, jak duży może być arkusz i jak można wpisywać do niego
dane.
Dowiedzieliśmy się także, że arkusz składa się z wierszy i kolumn, wyzna-
czających podział na komórki. Arkusz zawierający k wierszy i I kolumn ma więc
k x I komórek. Maksymalna liczba dostępnych komórek zależy od konkretnego
arkusza; w systemie Quattro Pro, mamy do dyspozycji arkusz o 8192 wierszach
i 256 kolumnach, a więc ten arkusz zawiera 2097152 komórki.
Początkowe 26 komórek z pierwszego wiersza ma adresy Al, Bl, Cl, ..., Yl,
Zl. Adresami następnych komórek są AAl, AB1, AC1, ..., AZ1 i dalej BA1,
BB1, BCl, ..., aż do IV1. Cztery rogi naszego arkusza mają więc współrzędne
(idąc zgodnie z ruchem wskazówek zegara) Al, IV1, IV8192 i A8192.
Pełny arkusz wydrukowany na papierze zająłby całą ścianę sporego budynku,
trudno więc oczekiwać, że zmieści się on na ekranie monitora. Podobnie więc jak
w przypadku edytora tekstów ekran jest oknem, przesuwającym się w dowolnym
kierunku w obrębie arkusza. Wielkość tego okna zależy od jakości obrazu wytwa-
rzanego przez monitor (tak zwanej rozdzielczości monitora); tutaj zakładamy, że
na ekranie można wyświetlić 25 wierszy po 80 znaków w każdym.
Skoncentrujmy teraz uwagę na obrazie z ekranu, pokazującym fragment arku-
sza. Po rozpoczęciu pracy z nowym arkuszem jest wyświetlany jego lewy górny
róg. Punktem odniesienia na ekranie jest kursor, znajdujący się w komórce,
9.2. Rozpoczynamy pracę
275
której zawartość możemy w danej chwili zmienić lub obejrzeć. Komórka ta na-
zywa się komórką bieżącą i jest podświetlona lub zaznaczona innym kolorem.
Położenie kursora zmieniamy za pomocą klawiszy sterujących kursorem (f,
i. Jeżeli podczas ruchu kursora
PgUp , PgDn
Ctrl
Ctrl
dojdziemy do krawędzi ekranu, to dalsze jego przesuwanie w tym samym kierunku
przesunie również okno ekranu względem całego arkusza.
Aby móc zmieniać zawartości komórek arkusza, oprócz metody adresowania
komórek, powinniśmy znać jeszcze polecenia wydawane programowi. Przyj-
rzyjmy się dokładnie wyglądowi całego obrazu na ekranie (rys. 9.4).
File Edit Style Graph Frint Database TodIs Options Windou
fil:
U A E C D E F G
1
Z
3
4
5
6
7
8
9
19
11
IZ
13
14
15
16
17
18
19
Z0
3-
SHEET1.UQ1 [1]
? Tl
i i 111 i i i i n! 111 i 1111 u i i 111 i 11111 im pm t n prrtw uni rui n n ftn n
FEADV
Rys. 9.4. Początkowy wygląd arkusza kalkulacyjnego na ekranie
Obraz na ekranie jest podzielony na trzy części. Centralna część pełni rolę
okna, przez które można oglądać fragment arkusza, składający się z 20 wierszy
i 7 kolumn. Wzdłuż lewej krawędzi są umieszczone kolejne liczby naturalne nu-
merujące wiersze, u góry zaś - litery opisujące kolumny. U dołu ekranu znajduje
się wiersz stanu programu, natomiast dwa górne wiersze służą do komunikowania
się użytkownika z programem.
Polecenia dla programu można z grubsza podzielić na dwie grupy:
1. Wpisz coś do wskazanej komórki (napis, liczbę lub wyrażenie).
2. Wykonaj inną, na ogół bardziej złożoną operację (skasuj, skopiuj, przenieś,
zapisz itp.).
276
9. Arkusz kalkulacyjny
Aby wydać polecenie z pierwszej grupy, należy ustalić za pomocą kursora
współrzędne komórki, w której ma być wykonany zapis, po czym wpisać odpo-
wiedni tekst w wierszu poleceń dla programu. Pierwszy wpisany znak informuje
program, co zamierzamy napisać. Jeżeli jest to litera, to zostanie ona uznana
za początek napisu i cały wiersz zostanie wiernie skopiowany do odpowiedniej
komórki. Również znaki specjalne ' (apostrof), " (podwójny apostrof) i " (da-
szek, na klawiaturze znajduje się nad cyfrą 6) oznaczają początek napisu. Dodat-
kowo każdy z nich inaczej umieszcza napis w komórce: po podaniu ' napis będzie
wyrównany do lewej krawędzi komórki, po " - wyrównany do prawej krawędzi,
a po * - umieszczony w środku komórki (centrowany). Znak specjalny nie jest
widoczny na ekranie - w komórce pojawia się tylko efekt jego działania.
Jeżeli pierwszy wpisany znak jest cyfrą lub którymś z operatorów (+, -, (, @
itp.), to wprowadzany tekst zostanie uznany za wyrażenie lub liczbę. Naturalnie
musi to być poprawne wyrażenie arytmetyczne - nawiasy muszą się zgadzać,
funkcje muszą mieć prawidłowe argumenty itp.
Polecenia z drugiej grupy są umieszczone w ofercie wyświetlanej w najwyż-
szym wierszu ekranu. Aby z niej skorzystać, należy nacisnąć klawisz /. Wówczas
jedno z poleceń zostaje podświetlone i zostanie wykonane, jeżeli naciśniemy kla-
wisz 1 Enter |. Jeśli chcemy wydać inne polecenie, to najpierw przenosimy pod-
świetlenie na jego nazwę, posługując się klawiszami strzałek lub naciskamy klawisz
z literą wyróżnioną w nazwie polecenia (oczywiście po naciśnięciu klawisza /).
Każde z poleceń u góry ekranu, po wybraniu, rozwija nową ofertę poleceń po-
tomnych, z których każde może być poleceniem ostatecznym (czyli do wykonania)
lub też rozwijać się dalej. Zasady poruszania się po podofertach są takie same,
jak w ofercie głównej. Z każdego poziomu ofert programu można wycofać się na
poprzedni poziom klawiszem JEsc |. Po wydaniu polecenia program zazwyczaj
pyta o wartości parametrów uściślających czynności, które mają być wykonane.
Arkusz akceptuje ponadto kilka poleceń wywoływanych przez naciśnięcie poje-
dynczego klawisza. Jednym z tych poleceń jest przejście kursorem do wybranego
fragmentu arkusza. W tym celu należy nacisnąć klawisz | F5 |, a następnie podać
adres komórki, którą chcemy mieć w lewym górnym rogu fragmentu arkusza
wyświetlanego na ekranie.
Przećwiczmy teraz podane wiadomości. Załóżmy, że w komórce Al chcemy
umieścić nazwisko Brzęczy szczykiewicz, a w komórce Bl jego rok urodzenia,
np. 1972. Przesuwamy więc kursor do komórki Al, po czym piszemy wymienione
nazwisko i na końcu naciskamy klawisz [Enter [. Następnie przesuwamy kur-
sor do Bl (klawiszem ?), wpisujemy liczbę 1972 i ponownie naciskamy klawisz
I Enter [. Pojawia się jednak przeszkoda gdyż komórka na prawo od komórki Al
jest zapełniona (liczbą 1972) i na ekranie widzimy jedynie fragment nazwiska
z komórki Al - Brzęczysz. Wynika to z niedopasowania rozmiarów komórki
9.3. Wyświetlanie liczb i zasięg poleceń
277
do długości nazwiska. Musimy zatem zmienić szerokość kolumny A. W tym
celu wybieramy z oferty polecenie /Style\ Column Width, a jako parametry poda-
jemy adres komórki (Al) i pożądaną szerokość (20 znaków). Możemy to uczynić
następującą sekwencją klawiszy: /SCAl|Enter |20[Enter |.
Poznaliśmy dwie ważne cechy elektronicznego arkusza: pamięta wszystko, co
umieszczamy w jego komórkach oraz potrafi zmieniać swój wygląd, na przykład
poszerzając pierwszą kolumnę. Ponadto w trakcie pracy można dodawać lub
usuwać wiersze bądź kolumny, kopiować lub przestawiać fragmenty arkusza, re-
dagować zawartość komórek (por. p. 9.6). Arkusz zatem ma podstawowe ce-
chy edytora tekstów - raz wprowadzone dane mogą być zmieniane, a następnie
wyświetlone w sposób najbardziej odpowiadający użytkownikowi.
W ostatnim wierszu ekranu jest umieszczany wiersz stanu programu. Opi-
suje on aktualny stan arkusza (nazwę bieżącego arkusza, numer okna itp.) lub
zawiera komentarz do wybieranego polecenia.
Najistotniejszy dla użytkownika jest wiersz wprowadzania danych, wyś-
wietlany w drugim wierszu ekranu. Pojawiają się w nim m.in.:
- dane wprowadzane do bieżącej komórki;
- aktualnie poprawiana zawartość komórki (po naciśnięciu klawisza | F2 |);
- rzeczywista zawartość bieżącej komórki oraz wartości jej parametrów: sze-
rokość, format numeryczny, krój pisma itp. (podczas przeglądania arkusza);
- pytania o wartości parametrów (podczas wykonywania poleceń z oferty).
9.3. Sposoby wyświetlania liczb,
zasięg działania poleceń
Załóżmy, że do komórki Bl wpisaliśmy liczbę 4600. Liczbę tę można wyświetlić
na wiele sposobów, zależnych od formatu wyświetlania, który wybieramy pole-
ceniem /Style\Numeric Format. Przykłady formatów i odpowiadająca im postać
liczby są podane w tablicy 9.1.
Tablica 9.1. Formaty numeryczne
Format
Postać liczby
Uwagi
General
4600
Najkrótsza postać (stalopozycyjna
lub wykładnicza)
Fixed
4600.00
Postać stałopozycyjna
Scientific
4.6E+03
Postać wykładnicza
4,600.00
Tysiące oddzielone przecinkami
We wszystkich przypadkach możemy również wybrać liczbę cyfr dziesiętnych
w części ułamkowej.
278
9. Arkusz kalkulacyjny
Zawartość komórki może być ukryta przed niepowołanym okiem (format Hid-
den) lub wyświetlona w postaci zapisanego w niej wyrażenia - w szablonie arku-
sza, por. rys. 9.2 (format Text).
Zasięgiem działania formatu może być pojedyncza komórka (np. Cl), frag-
ment wiersza (np. D3..H3), fragment kolumny (np. G1..G20) lub najogólniej -
dowolny prostokątny fragment arkusza (np. C3..G15). Umiejętność określania
fragmentu arkusza (zwanego często blokiem) o jaki nam chodzi, jest bardzo
istotna - program pyta nas o to niemal przy każdym wydawanym mu poleceniu.
i
9.4. Nieco o wyrażeniach
Przypomnijmy, że w każdej komórce arkusza można umieścić napis albo wzór,
czyli wyrażenie, symbolizujące pewną wartość liczbową. Zacznijmy od najprost-
szych (zakładamy, że umieszczono je w komórce Al):
4600 - Jest to stała liczbowa. Zgodnie z informacjami z p. 9.3 sposób wyś-
wietlania liczb zależy od obowiązującego w danej chwili formatu wyś-
wietlania, pełniącego funkcję pośrednika pomiędzy wyrażeniem, a jego
wartością.
+C3 - Jest to adres komórki i oznacza skopiowanie do komórki Al wartości
wyrażenia znajdującego się w komórce C3. Wyrażenie to jest poprze-
dzone znakiem + (plus), gdyż sam adres C3 zostałby potraktowany
przez arkusz jako napis (ponieważ zaczyna się od litery - por. p. 9.2).
Większość wyrażeń w arkuszu rozpoczyna się znakiem +, który w tym
kontekście jest najwygodniejszy, gdyż nie zmienia wartości wyrażenia.
Mając do dyspozycji stałe liczbowe, adresy komórek i operatory arytmetyczne,
możemy konstruować wyrażenia arytmetyczne (por. rozdz. 4). Umożliwiają one
wykonywanie obliczeń na podanych argumentach. Zacznijmy od wyliczenia ope-
ratorów (w kolejności malejących priorytetów tablica 9.2).
Tablica 9.2. Operatory arytmetyczne
Priorytet
Operator
Znaczenie
4
( )
zmiana kolejności obliczeń
3
podniesienie do potęgi
2
*
mnożenie
2
1
dzielenie
1
+
dodawanie
1
-
odejmowanie
9.5. Prosty model symulacyjny
279
Teraz kilka przykładów wyrażeń z komórek arkusza:
2~7
+A1-7
+C3+B5*2.5
(Bl+44)/2
@SIN(C5)~2
Jak widać, wyrażenie, ów kalkulator związany z komórką, w której go umie-
szczono, dzięki możliwościom pobierania danych z innych komórek dysponuje
większymi możliwościami niż typowy kalkulator. Arkusz stawia ponadto do dys-
pozycji użytkownika dużą liczbę funkcji (nazwy wszystkich funkcji zaczynają się
od znaku @ - jedną z nich poznaliśmy już w p. 9.1). Są to zarówno funkcje znane
użytkownikom kalkulatorów (obliczanie pierwiastka kwadratowego, funkcje try-
gonometryczne itp.), jak i funkcje specyficzne dla arkusza (operacje na datach,
obliczenia finansowe, funkcje logiczne). W następnych punktach przekonamy się,
że dzięki tym możliwościom postać wyrażenia może być bardzo złożona, w dużej
mierze decydując o atrakcyjności arkusza.
9.5. Prosty model symulacyjny
Zastosujmy w praktyce nabytą wiedzę, próbując odpowiedzieć na pytanie: jaki
będzie mój kapitał pieniężny po kilku latach, jeżeli złożę 1000 tys. zł w banku
gwarantującym odsetki w wysokości 10% w skali rocznej. Nasze rozterki rozwiąże
arkusz o szablonie przedstawionym na rysunku 9.5.
1
2
3
4
5
6
7
8
A
odsetki:
kapitał:
B
10
1000
Bank PKO
Wysokość kapitału na końcu:
roku 1
+B2*(l+Bl/100)
roku 2
+B7*(l+Bl/100)
roku 3
+C7*(l+Bl/100)
Rys. 9.5. Naliczanie odsetek od złożonego kapitału - szablon arkusza
Z wyglądu arkusza wynika, że wydano już polecenie powiększenia szerokości
kolumn B, C i D do 14 znaków (poleceniem /Style\Block Size\Set Width z para-
metrem 14). Dla napisu w komórce B4 (Wysokość kapitału na końcu:) jest to
jednak nadal za mało miejsca - napis rozciąga się na dwie kolumny. W ten sposób
280
9. Arkusz kalkulacyjny
arkusz wyświetla długie napisy: zasłaniają one komórki na prawo od zajmowanej,
ale pod warunkiem, że te komórki są wolne.
Dla zwiększenia czytelności arkusza wskazane byłoby jeszcze dosuwanie war-
tości liczbowych do prawego marginesu i wyświetlanie ich z dwoma miejscami po
kropce. Zawartość arkusza po tych operacjach jest przedstawiona na rys. 9.6.
A
B
C
D
1
odsetki:
10.
00 Bank
PKO
2
kapitał:
1000.
00
3
4
Wysokość
kapitału na
końcu:
5
6
roku 1
roku
2
roku 3
7
1100.
00
1210.00
1331.00
8
Rys. 9.6. Naliczanie odsetek od złożonego kapitału - zawartość arkusza
Jeżeli chcemy prześledzić narastanie kapitału dla zmienionego oprocentowa-
nia lub innego kapitału początkowego, to wystarczy zmienić dane w komórkach
odpowiednio Bl lub B2. Program automatycznie obliczy i wyświetli w wierszu
7 nowe wartości. Jeżeli założymy, że rozbudowujemy nasz arkusz w ten sposób,
aby wysokość kapitału na końcu trzeciego roku była wielkością początkową dla
wykonania 100 dalszych obliczeń, zysk czasowy będzie naprawdę spory.
9.6. Nanoszenie poprawek
Arkusz kalkulacyjny ma wszelkie cechy zwykłej kartki papieru: można wymazać
z niego niepotrzebne dane (/Edit\EraseBlock), zmodyfikować istniejące (klawisz
|F2 |), lub też rozciąć arkusz wzdłuż wybranego wiersza lub kolumny i usunąć
(/Edit\Delete) bądź dodać (/Edit\Insert) wiersz lub kolumnę. Jeżeli skonstru-
owany arkusz zupełnie nie przypadł nam do gustu, wyrzucamy całą kartkę do
kosza (/File\Erase) i rozpoczynamy pracę od nowa.
Przeredagujmy nieco arkusz z rys. 9.6. Najpierw usuwamy nazwę banku, prze-
chowującego nasze oszczędności - polecenie /Edit\Erase Błock Cl |Enter |. Jeśli
chcemy uzupełnić napis w komórce B4, nie pisząc go od nowa, to możemy sko-
piować go najpierw do wiersza poleceń (naprowadzamy kursor na B4 i naciskamy
|~F2~|) a następnie zredagować według potrzeb. Drażni nas pusty wiersz 5 - usu-
wamy go poleceniem /Edit\Delete\Rows A5|Enter |. Chcemy dodać pusty wiersz
i pustą kolumnę odpowiednio na górnym i lewym obrzeżu arkusza - realizują to
polecenia /Edit\InserĄRow Al | Enter | i /Edit\Insert\ Column Al | Enter |.
9.6. Nanoszenie poprawek
281
Usunięcie piątego wiersza, a w istocie zbliżenie wierszy 4 i 6, można rozwiązać
inaczej, przenosząc dolny fragment arkusza o jeden wiersz w górę poleceniem
/Edit\Move B6..D7] Enter]B51 Enter].
Po dodaniu skrajnej kolumny zaczynamy mieć wątpliwości, gdyż w dawnym
wierszu siódmym były wyrażenia zawierające adresy komórek (por. rys. 9.6). Po
wstawieniu nowej pustej kolumny numer 1, komórka B2 stała się komórką C2, B7
przeszła na C7 itd. Nie musimy jednak przeredagowywać całego arkusza, gdyż
program zrobił to już automatycznie.
Ogólnie, arkusz traktuje adresy komórek na trzy sposoby. Przedstawimy je,
analizując możliwe warianty skopiowania lub przeniesienia wzoru z komórki A2
do komórki D4:
1. Adres jest wielkością względną. Na przykład wyrażenie +A1 umieszczone
w komórce A2 oznacza wartość wyrażenia z komórki położonej w tej sa-
mej kolumnie, ale o jeden wiersz wyżej (rys. 9.7). Po skopiowaniu do
komórki D4 wyrażenie to przybierze postać +D3 (tzn. ta sama kolumna,
wiersz bezpośrednio wyżej).
B
D
1
2
3
4
+A1
+D3
Rys. 9.7. Adres względny
2. Adres jest wielkością bezwzględną, niezależną od zmian dokonywanych
w arkuszu. Takie adresy wpisujemy poprzedzając numer wiersza i literę
kolumny komórki znakiem $ (rys. 9.8).
A B C D
2
3
4
+$A$1
+$A$1
Rys. 9.8. Adres bezwzględny
3. Część adresów w wyrażeniu jest względna, a część bezwzględna, np. wyra-
żenie +$A1 w komórce A2 oznacza "wartość wyrażenia z komórki w kolu-
mnie A i w wierszu bezpośrednio powyżej". Przy kopiowaniu do komórki
D4 wyrażenie ulegnie zmianie na +$A3 - kolumna A, wiersz bezpośrednio
powyżej wiersza czwartego (zob. rys. 9.9).
282
9. Arkusz kalkulacyjny
.C
1
2 +$A1+B$2 -
3
4
D
+$A3+E$2
Rys. 9.9. Adresy mieszane
9.7. Zakończenie pracy
Aby zakończyć pracę z arkuszem, wydajemy polecenie /File\Exit. Wykonanie
tego polecenia powoduje powrót pod nadzór systemu operacyjnego. Mogłoby
zatem spowodować utratę zawartości arkusza, jeśli uprzednio nie zapisaliśmy wy-
ników naszej pracy na dysku lub dyskietce. Służy do tego polecenie /File\Save.
Jeśli nie pamiętaliśmy o tym, to przed zakończeniem pracy program sam to nam
zaproponuje, dając szansę zapisania bieżącego stanu arkusza. Jeśli po jakimś cza-
sie chcemy wrócić do naszego arkusza, to należy odczytać go z pliku poleceniem
/File\ Open.
Podobnie, jak w przypadku korzystania z innych systemów oprogramowania
(takich jak język Pascal czy edytor TAG), operację składowania rezultatów pracy
w pamięci masowej powinno się powtarzać przynajmniej co pół godziny, gdyż
nic nie przywróci nam informacji utraconych w następstwie chwilowego spadku
napięcia lub innych zakłóceń.
Wymienione tutaj polecenia, być może inaczej nazwane i inaczej wywoływane,
występują w większości programów usługowych i warto je zapamiętać.
9.8. Skomputeryzowane przyznawanie premii
Uzbrojeni w znaczną już wiedzę przystępujemy do rozwiązania praktycznego pro-
blemu - zarządzania firmą. Przypuśćmy, że jesteśmy właścicielem małego, dobrze
prosperującego przedsiębiorstwa i jako dobry szef chcemy wynagrodzić pracow-
ników, przyznając im premie. W celu określenia premii (liczonej w procentach
pensji) sumujemy dwa składniki: naszą własną opinię o podwładnych oraz ich staż
pracy (który będziemy mnożyć przez dwa). Stawiamy tylko jedno ograniczenie,
by suma premii nie przekroczyła 10% zysku firmy.
Na przeszkodzie do szybkiego rozwiązania postawionego zadania stoi trudność
z obliczeniem stażu pracy. W przypadku arkusza dysponujemy jednak całą gamą
funkcji działających na datach. Umożliwiają one wpisywanie dat do arkusza oraz
wykonywanie niektórych działań na datach (dodanie i odjęcie liczby, odejmowanie
dat od siebie itp.).
9.8. Skomputeryzowane przyznawanie premii
283
Wpisywanie dat odbywa się w arkuszu za pomocą funkcji @DATE, której trzema
parametrami są rok, miesiąc i dzień. Jeżeli jakiś pracownik został zatrudniony
15 października 1987 roku, to w odpowiedniej komórce umieszczamy następujące
wyrażenie @DATE(87,10,15). Bieżąca data jest wartością funkcji (3T0DAY (bez
parametrów).
A B C D
1 Imię Data zatrudnienia Pensja Staż pracy
2 Andrzej <żDATE(87,10,15) 1800 @INT((@T0DAY-B2)/365)
1 Składnik
2 6
E
Premia
+C2*(E2+D2*2)/100
Rys. 9.10. Obliczanie premii - szkic szablonu arkusza
Obliczenie stażu pracy, który jest liczony w pełnych latach, polega na odjęciu
daty zatrudnienia od bieżącej daty, podzieleniu wyniku przez 365 (tyle dni liczy
rok) i zaokrągleniu ilorazu w dół. Zatem jeśli data zatrudnienia jest umieszczona
w komórce B3, to w komórce np. D3 możemy wpisać wzór realizujący obliczanie
lat stażu: @INT((@T0DAY-B3)/365). Wartością użytej tu funkcji @INT jest część
całkowita z podanego argumentu.
Jeśli oceniamy pracownika na 6-procentową premię, a jego staż pracy wynosi
1 rok, to premia powinna wynieść 6+1*2 procent. Początkowy fragment szablonu
arkusza jest przedstawiony na rys. 9.10 (z braku miejsca arkusz został złamany
i przedstawiony w dwóch wierszach). Zakładamy, że wszystkie kwoty są podane
w tysiącach złotych.
Widać już, że przy wpisywaniu danych o następnych pracownikach wyrażenia
w kolumnach D i F będą się różnić jedynie numerami wiersza, np. w komórce D3
zamiast @T0DAY-B2 będzie OT0DAY-B3 itd. Powielenie wyrażenia z uwzględnieniem
wymienionej modyfikacji można zlecić arkuszowi. Polecenie /Edit\ Copy umożli-
wia kopiowanie wyrażenia, traktując zawarte w nim adresy jako względne (gdyż
oznaczenia wierszy i kolumn nie są poprzedzone znakiem $ - por. p. 9.6). Jeśli
chcemy więc dopisać jeszcze trzech pracowników do naszej listy osób nagrodzo-
nych premią, to kolumnę F wypełniamy stosując polecenie kopiowania z parame-
trami F2 (komórka źródłowa) i F3..F5 (blok komórek docelowych). Analogicznie
wypełniamy kolumnę D. Postać szablonu po tym uzupełnieniu jest pokazana na
rysunku 9.11.
286
9. Arkusz kalkulacyjny
A
B
C
D
1
Imię
Data zatrudnienia
Pensja Staż
pracy
2
Andrzej
15/10/87
1800.00
1
3
Jacek
01/06/85
2000.00
3
4
Piotr
15/09/86
1700.00
2
5
Anna
01/07/87
1650.00
0
6
7
8
Zysk firmy:
8820.00
9
Pula na premie:
882.00
10
Suma premii:
880.50
1
2
3
4
5
E
Składnik
7.5
8.5
10
11
F
Premia
171.00
290.00
238.00
181.50
Rys. 9.13. Obliczanie premii - wersja końcowa wyników
300-1
250-
200-
150-
100-
50-
I
Andrzej
Jacek
Piotr
Anna
Rys. 9.14. Ilustracja graficzna wielkości przyznanych premii - wykres
słupkowy
9.10. Funkcje logiczne
287
Możliwości arkusza Quattro Pro w dziedzinie graficznej prezentacji danych są
bardzo duże. W ofercie programu są one umieszczone pod wspólnym poleceniem
/Graph. Aby narysować wykres taki, jak na rys. 9.14, wystarczy zdefiniować od-
powiednie serie (czyli ciągi liczb lub napisów, definiujących argumenty i wartości
wykreślanych funkcji). Serię dla osi Ox (w naszym przypadku są to imiona pra-
cowników) definiujemy wydając polecenie /Graph\Series\X-Axis Series i podając
jako parametr blok A2..A5. Podobnie definiujemy pierwszą (i w naszym przy-
padku jedyną) serię dla osi Oy /Graph\Series\lst Series z parametrem F2..F5.
Wykonany wykres możemy obejrzeć wybierając z oferty polecenie /Graph\ View.
Jeżeli nie jesteśmy w pełni zadowoleni z postaci wykresu, to możemy zmienić
niektóre jego parametry. Na przykład aby obejrzeć obliczone wysokości premii
w postaci wykresu kołowego, można zmienić rodzaj wykresu za pomocą po-
lecenia /Graph\Graph Type\Pie (por. rys. 9.15). W każdym przypadku program
automatycznie dobiera skalę dla wykresu - jeżeli nam nie odpowiada, to możemy
oczywiście ją zmienić.
Anna (20.6%)-^
Piotr (27.0%)
Andrzej (19.4%)
Jacek (32.9%)
Rys. 9.15. Ilustracja graficzna wielkości przyznanych premii - wykres kołowy
9.10. Funkcje logiczne
W arkuszu czasami jest konieczne uzależnienie wykonania jakiejś operacji od
danych umieszczonych w innym miejscu. Przykładowo, wzór obliczający premię
(por. rys. 9.10) moglibyśmy zmodyfikować i każdemu pracownikowi ze stażem
przynajmniej 10-letnim dodawać ekstra 5% do premii. Do zapisywania operacji
warunkowych służy funkcja @IF. Jej ogólna postać jest następująca:
288
9. Arkusz kalkulacyjny
(9IF (warunek, wyrażenie-tak, wyrażenie-nie)
a działanie - analogiczne do opisanej w rozdziale 4 instrukcji if... then.,. else...
Oznacza to, że jeśli warunek jest spełniony, to obliczana jest wartość wyrażenia-
tak, a w przeciwnym razie - wyrażenia-nie. Zatem, aby dodawać 5% premii
pracownikom ze stażem przynajmniej 10-letnim, w komórce F2 z rys. 9.11 należy
umieścić następujące wyrażenie:
+C2/100*(E2+D2*2+@IF(D2<0,0,5))
Następnie należy skopiować zawartość komórki F2 do bloku F3..F5, aby ta mo-
dyfikacja dotyczyła wszystkich pracowników.
nn Uwaga: Arkusz obliczający premie znajduje się na dyskietce w pliku PREMIE.WQ1 umie-
szczonym w kartotece R0ZDZ9.
Korzystając z funkcji @IF, zmodyfikujmy teraz arkusz z rys. 9.5 tak, aby
obliczał wielkość kapitału po dowolnej liczbie lat. Szablon w nowej postaci jest
przedstawiony na rys. 9.16, a sam arkusz - na rysunku 9.17.
A
B
1
Start obliczeń
: 0
2
Procent:
10
3
Kapitał pocz:
1000.00
1
2 Koniec roku:
3 Kapitał:
D
IF(Bl=0,0,l+D2)
@IF(B1=O,B3,(l+B2/100)*D3)
Rys. 9.14. Obliczanie odsetek od kapitału - druga wersja szablonu z rys. 9.5
A B
1 Start obliczeń: 0
2 Procent: 10
3 Kapitał początkowy: 1000.00
Koniec roku:
Kapitał:
0
1000.00
Rys. 9.15. Obliczanie odsetek od kapitału - stan początkowy obliczeń
Obliczenia w tym arkuszu są inicjowane w komórce Bl i po zmianie jej za-
wartości na różną od zera (np. na 1), arkusz przybiera postać jak na rys. 9.18.
9.11. Arkusz a metody numeryczne
289
Naciśnięcie następnie klawisza |F9 | (co wymusza jednokrotne przeliczenie wszyst-
kich wyrażeń) spowoduje zmianę wartości odpowiednich komórek (por. rys. 9.19).
A B
1 Start obliczeń: 1
2 Procent: 10
3 Kapitał początkowy: 1000.00
Koniec roku:
Kapitał:
1100.00
Rys. 9.16. Obliczanie odsetek od kapitału - rozpoczęcie obliczeń
Cechą tej modyfikacji jest m.in. niewychodzenie poza obręb ekranu niezależnie
od tego czy analizujemy wzrost kapitału po trzech, czy po dwudziestu latach. Za-
uważmy bowiem, że w szablonie z rys. 9.5 wyrażenie obliczające wielkość kapitału
po 7 latach musielibyśmy umieścić w skrajnej kolumnie H, a wpisanie następnych
wzorów wiązałoby się z koniecznością przesunięcia okna ekranu w prawo po ar-
kuszu.
A
B
C
D
1
Start obliczeń:
1
2
Procent:
10
Koniec roku:
2
3
Kapitał początkowy:
1000.00
Kapitał:
1210.00
Rys. 9.17. Obliczanie odsetek od kapitału - kolejny krok obliczeń
9.11. Arkusz a metody numeryczne
Arkusz kalkulacyjny został szybko dostrzeżony i doceniony przez użytkowników
spoza kręgu handlu i ekonomii. Jednym z jego możliwych zastosowań jest wy-
konywanie obliczeń według algorytmów numerycznych. Rozważmy algorytm
Newtona-Raphsona, obliczający pierwiastek kwadratowy z nieujemnej liczby
rzeczywistej a (por. p. 6.7.2 i zad. 6.4). Po ustaleniu przybliżenia początkowego
xq, następne przybliżenia są obliczane według wzoru:
1
a
H )
Tworzenie arkusza zaczniemy od rzeczy najprostszych: wpisania wartości po-
czątkowych i powyższego wzoru. Przyjmijmy a = 45 i xq = 7. Szkic tworzonego
szablonu jest przedstawiony na rysunku 9.20.
19 Elementy informatyki
290
9. Arkusz kalkulacyjny
A
B
C
D
1
Pierwiastek
z liczby:
45
2
Przybliżenie
początkowe:
7
3
4
Krok iteracji
Wartość
przybliżenia
5
0
+C2
6
+B5+1
0
5*(C5+($C$1/C5))
Rys. 9.18. Szkic szablonu arkusza dla algorytmu Newtona-Raphsona
Ułatwiamy sobie zadanie przy wpisywaniu kolejnych numerów kroku iteracji -
w kolumnie B będziemy po prostu zwiększać o 1 wartości w kolejnych wierszach.
Do skopiowania wzorów z wiersza 6 użyjemy polecenia /Edit\ Copy z parametrami
B6..C6 (blok źródłowy) i B7..C14 (blok docelowy). Kompletny szablon arkusza
jest przedstawiony na rysunku 9.21.
Pierwiastek z liczby:
Przybliżenie początkowe:
B
C
45
we: 7
Krok iteracji
Wartość przybliżenia
0
+B2
+B5+1
0.5*(C5+($B$l/C5))
+B6+1
0.5*(C6+($B$l/C6))
+B7+1
0.5*(C7+($B$l/C7))
+B8+1
0.5*(C8+($B$l/C8))
+B9+1
0.5*(C9+($B$l/C9))
+B10+1
0.5*(C10+($B$l/C10))
+B11+1
0.5*(Cll+($B$l/Cll))
+B12+1
0.5*(C12+($B$l/C12))
+B13+1
0.5*(C13+($B$l/C13))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Rys. 9.19. Kompletny szablon arkusza dla algorytmu Newtona-Raphsona
Po obliczeniu wartości wyrażeń zawartość arkusza ma postać przedstawioną
na rysunku 9.22.
Jeżeli chcemy zbadać wrażliwość algorytmu na przybliżenie początkowe, to
wystarczy zmienić liczbę w komórce B2 i ponownie obejrzeć obraz na ekranie
(rys. 9.23). Te dwa wykonania algorytmu przekonują nas, że zgodnie z opisem
teoretycznym, algorytm Newtona-Raphsona jest dość szybko zbieżny, niezależnie
od wybranego przybliżenia początkowego.
9.11. Arkusz a metody numeryczne
291
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Pierwiastek z liczby:
Przybliżenie początkowe:
45
7
Krok iteracji Wartość przybliżenia
0 7
1 6.7142857142857
2 6.7082066869301
3 6.7082039324999
4 6.7082039324994
5 6.7082039324994
6 6.7082039324994
7 6.7082039324994
8 6.7082039324994
9 6.7082039324994
Rys. 9.20. Obliczanie pierwiastka kwadratowego - wyniki obliczeń
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Pierwiastek z liczby:
Przybliżenie początkowe:
45
100
Krok iteracji Wartość przybliżenia
0 100
1 50.225
2 25.560484071677
3 13.660507054956
4 8.4773373369942
5 6.892803935925
6 6.7106758700143
7 6.7082043877795
8 6.7082039324994
9 6.7082039324994
Rys. 9.21. Obliczanie pierwiastka kwadratowego - wyniki dla innego
przybliżenia początkowego
Uwaga: Arkusz realizujący algorytm Newtona-Raphsona znajduje się na dyskietce w
pliku PIER.WIAS.WQ1 umieszczonym w kartotece R0ZDZ9.
292
9. Arkusz kalkulacyjny
Przedstawiony powyżej szablon jest klasycznym przykładem sposobu realizo-
wania w arkuszu algorytmów iteracyjnych. Pętlę iteracyjną zastępuje się tutaj
iteracją wzdłuż jednego z wymiarów arkusza. W ten sposób zawsze widzimy wy-
niki wszystkich obliczeń i możemy natychmiast ocenić skuteczność metody (na
nodstratlanvch liczbowych lub korzystając z wykresu obrazującego odpowie-
dnie zEMości). Również badanie zależności wyników od danych początkowych
jest ufljpfone - wystarczy zmienić wartość w odpowiedniej komórce, a arkusz
natychmiast wykona wszystkie zapisane w nim obliczenia.
9.12. Nowy system programowania?
*
Spróbujmy teraz krytycznie spojrzeć na arkusz kalkulacyjny. Cechą rzucającą się
w oczy i wielką zaletą tego programu jest naturalność zapisu algorytmów. Kon-
struując każdy z omawianych arkuszy postępowaliśmy przecież praktycznie tak
samo, jak przy wykonywaniu obliczeń ręcznych na kartce papieru i z ewentualną
pomocą kalkulatora.
Ponieważ omawiane przykłady można również rozwiązać wykorzystując język
programowania, np. znany już z wcześniejszych rozdziałów Pascal, naturalnym
będzie porównanie tych dwóch sposobów.
Arkusz kalkulacyjny na ogół zawodzi przy rozwiązywaniu złożonych
dnień, gdzie przydatna jest m.in. technika programowania strukturalnego, ułat-
wiająca rozwiązywanie problemów i zwiększająca czytelność opisu rozwiązań. Po-
nadto porównanie szybkości wykonania algorytmu zapisanego w języku progra-
mowania z szybkością oferowaną przez arkusz również wypada najczęściej na
niekorzyść tego ostatniego.
Stosowanie arkusza zwalnia nas jednak z obowiązku pamiętania o sztywnej
składni, właściwej większości języków programowania, a także dokładniejszej
znajomości sprzętu. Użytkownik w niemal naturalny sposób podaje, co ma
być zrobione (wpisz do komórki liczbę 10; posortuj pierwsze dziesięć wierszy
rosnąco według zawartości trzeciej kolumny itp.) i może nie interesować się,
jak będzie to realizowane. Nie ma tu mowy o niezgodności typów, brakującym
średniku, niewłaściwej kolejności parametrów. Zapominamy o uciążliwych ope-
racjach czytania danych i wyprowadzania wyników - są one po prostu tam, gdzie
umieściliśmy wzory, a konwersacja z programem odbywa się w sposób ciągły.
Wpisywanie danych i nanoszenie poprawek jest wykonywane w miejscu, w którym
dane są wyświetlane. Wyniki otrzymujemy na bieżąco, również w tym samym
miejscu.
Posługiwanie się w arkuszu bardziej złożonymi strukturami danych jest moż-
liwe dzięki dopuszczeniu odwołań symbolicznych w miejsce adresów komórek.
Realizuje się to poleceniem /Edit\Names\Create (parametry: nazwa symboliczna
9.13. Podsumowanie
293
i blok komórek, który ma reprezentować). W ten sposób można np. obszar F2..F5
z rys. 9.11 opatrzyć nazwą PREMIE, po czym zamiast wyrażenia @SUM(F2. .F5)
napisać <3SUM(PREMIE).
Ważkim argumentem na korzyść arkusza jest także znacznie krótszy czas po-
trzebny do nabrania wprawy w korzystaniu z niego w porównaniu zM gfm> P
którym będziemy umieli równie sprawnie zapisywać algorytmy uży\\R| języka
programowania. Stwarza to nowe perspektywy w stosowaniu kompulŁpJF przez
osoby mało obeznane z językami programowania. Niemniej, używanie arkusza,
podobnie jak wielu innych gotowych programów, wymaga od użytkownika po-
siadania wielu cech charakteryzujących m.in. programistę. Osoba nie umjejąca
sformułować algorytmu rozwiązującego dany problem, nie rozumiejąca np. pojęcia
warunku logicznego czy też podstawowych pojęć matematycznych, będzie równie
bezradna pisząc program w języku Pascal, jak i zasiadając przed ekranem z ar-
kuszem kalkulacyjnym.
Czy można więc uznać arkusz za system programowania? Wielu użytkowni-
ków daje na to pytanie odpowiedź twierdzącą.
9.13. Podsumowanie
Ę tego rozdziału było przede wszystkim zachęcenie do korzystania z arkusza
kalkulacyjnego na przykładzie programu Quattro Pro.
Aby skutecznie i umiejętnie prowadzić konwersację' z arkuszem, trzeba nau-
czyć się przewidywać jego działanie w odpowiedzi na nasze polecenia. W tym
celu należy poznać funkcjonalny model działania arkusza. Zamiast więc przeka-
zywać wszystkie szczegółowe informacje o programie chcieliśmy, aby Czytelnik
zrozumiał koncepcję i poznał niektóre z możliwości arkusza, by następnie móc
eksperymentować z dowolnymi programami tego typu.
Opisane wyżej cechy programu Quattro Pro ma większość programów z grupy
arkuszy kalkulacyjnych. Różnice mogą dotyczyć m.in. sekwencji klawiszy używa-
nych do wykonania poszczególnych czynności, szczegółów w sposobie ich działania
oraz obecności lub braku udogodnień dla użytkownika (istniejące funkcje, możli-
wości graficzne, układ poleceń w ofercie itp.).
Tak więc zasiadając przed ekranem komputera, po uruchomieniu dowolnego
programu typu arkusz kalkulacyjny powinniśmy umieć zadawać pytania i od-
powiadać na nie. Przykładowo, w jaki sposób odbywa się wydawanie poleceń:
przez ich napisanie w wyodrębnionym do tego wierszu czy przez wybór z gotowej
oferty? Jakie są możliwe sposoby wyświetlania liczb? Jakie są dostępne działania
na datach? Odpowiedzi znajdujemy przeglądając dokumentację, pytając innego
użytkownika lub metodą prób i błędów. Droga do opanowania arkusza - tak jak
każdego innego programu użytkowego - wiedzie przez praktykę.
294
9. Arkusz kalkulacyjny
Arkusz może stanowić cenne narzędzie nie tylko dla profesjonalnych użytkow-
ników komputerów, ale również dla przeciętnego "zjadacza bitów". Tak więc,
jeżeli zajdzie potrzeba kontrolowania własnych wydatków albo szybkiego spraw-
dzenia przyrostu konta po trzech latach, z uwzględnieniem pięciu wariantów opro-
centowania lub gdy po prostu zapragniemy nietypowej rozrywki intelektualnej -
pamiętajmy o arkuszu kalkulacyjnym.
Zadania
9.1. Wyjaśnij różnicę między liczbą (wyrażeniem) 123 a napisem 123. Czy ich
postać podczas wyświetlania zawartości arkusza może być taka sama? Zapropo-
nuj metodę łączenia w jednej komórce napisów i liczb.
9.2. Podaj sposób zamiany miejscami bloków kolumnowych A1..A10 i Cl..CIO,
korzystając z polecenia przenoszenia (/Edit\Move).
Wskazówka: Zamiana wartości zmiennych a i c w języku Pascal jest wyko-
nywana za pomocą zmiennej pomocniczej rob w następujący sposób: rob:=a;
a:=c; c:=rob.
9.3. Znajdź i wypisz podobieństwa między Twoim ulubionym edytorem tekstów,
a arkuszem kalkulacyjnym w zakresie czynności redakcyjnych (np. przenoszenie
bloków, wyszukiwanie tekstów itp.).
9.4. Zaprojektuj szablon arkusza obliczającego miesięczne wydatki z budżetu do-
mowego (z podziałem na grupy: żywność, opłaty stałe itp.).
9.5. Zaprojektuj szablon arkusza zawierającego nazwiska uczniów, ich oceny
cząstkowe i końcowe z matematyki, średnią z ocen dla ucznia oraz średnią ocen
dla całej klasy (por. zadania 4.10 i 4.11).
9.6. Zaprojektuj szablon arkusza kontrolującego dłużników firmy; uwzględnij wy-
sokość długu, termin płatności oraz kary za przekroczenie tych terminów.
9.7. Zaprojektuj szablon arkusza obliczającego największy wspólny dzielnik dwóch
liczb metodą Euklidesa (por. rozdz. 4 i algorytm 4.4).
9.8. Zaprojektuj szablon arkusza obliczającego metodą Homera wartość wielo-
mianu o podanych współczynnikach w zadanym punkcie (por. p. 6.3).
9.9. Zaprojektuj szablon arkusza obliczającego 10 kolejnych wyrazów (od dj do
ciągu Fibonacciego (por. zad. 4.4 i 4.5).
9.10. Zaprojektuj szablon arkusza obliczającego średnią arytmetyczną i odchy-
lenie standardowe 20 podanych liczb (por. rozdz. 4 i algorytm 4.6).
DODATEK
Tabela kodów ASCII
Znak
Kod
Znak
Kod
Znak
Kod
Znak
Kod
spacja
32
8
56
P
80
h
104
!
33
9
57
Q
81
i
105
it
34
58
R
82
j
106
#
35
i
59
S
83
k
107
$
36
<
60
T
84
1
108
1
37
=
61
U
85
m
109
k
38
>
62
V
86
n
110
y
39
63
W
87
o
111
(
40
@
64
X
88
P
112
)
41
A
65
Y
89
q
113
*
42
B
66
Z
90
r
114
+
43
C
67
[
91
s
115
>
44
D
68
\
92
t
116
-
45
E
69
]
93
u
117
46
F
70
-
94
V
118
/
47
G
71
95
w
119
0
48
H
72
c
96
X
120
i
49
I
73
a
97
y
121
2
50
J
74
b
98
z
122
3
51
K
75
c
99
{
123
4
52
L
76
d
100
1
124
5
53
M
77
e
101
>
125
6
54
N
78
f
102
126
7
55
0
79
g
103
Del
127
Kody od 0 do 31 są przyporządkowane znakom sterującym.
Tabela kodów liter polskich w standardzie Mazovia
Znak
Kod
Znak
Kod
Znak
Kod]
ą
134
1
146
ś
158
ć
141
ń
164
ź
166
ę
145
ó
162
ż
167
Ą
143
Ł
156
Ś
152
Ć
149
N
165
Ź
160
Ę
144
O
163
Z
161
?
OMÓWIENIE LITERATURY
UZUPEŁNIAJĄCEJ
Wymienione poniżej książki polecamy jako literaturę uzupełniającą rozważania
prowadzone w podręczniku (EI-I) i w rozwiązaniach zadań (EI-II).
Informatyka, jako dziedzina zajmująca się algorytmami, jest przystępnie przed-
stawiona w następującej książce, która powstała na kanwie pogadanek radiowych
wygłaszanych przez jej autora:
D. Harel, Rzecz o istocie informatyki. Algorytmika, WNT, Warszawa 1992.
Najpełniejszy opis historii komputerów w języku polskim, od starożytności do
końca II wojny światowej, jest zawarty w książce:
R. Ligonniere, Prehistoria i historia komputerów, Ossolineum, Wrocław 1992.
Z historią komputerów w zwartej postaci można się zapoznać czytając:
H. Kaufman, Dzieje komputerów, PWN, Warszawa 1980.
Wszechstronne omówienie wpływu komputerów, a w ogólności - mikroelek-
troniki, na stosunki w społeczeństwie przedstawia Raport opracowany dla Klubu
Rzymskiego:
Mikroelektronika i społeczeństwo. Na dobre czy na złe?, red. G. Friedricks,
A. Schaff, Książka i Wiedza, Warszawa 1987.
System operacyjny MS-DOS w wersji 3.3 jest opisany w książce:
J. Deminet, System operacyjny MS-DOS, WNT, Warszawa 1990.
Pełny opis systemu i języka AC-Logo można znaleźć w jego dokumentacji
opracowanej przez autorów tego systemu:
Podręcznik użytkownika AC-Logo. Wersja 1.2 dla IBM-PC, Wydawnictwo OFEK
Jelenia Góra, Jelenia Góra 1993.
Następujące opracowania (podajemy je w porządku chronologicznym) trak-
tują o metodach programowania wykorzystujących wersje języka Logo dla różnych
komputerów. Większa część każdej z tych książek zawiera materiał, który nie
zależy od wybranej wersji języka, mogą więc one być przydatne także dla użyt-
kowników systemu AC-Logo.
E. Gurbiel, H. Krupicka, Z. Ploski, Programowanie i Logo, Wydawnictwo Uni-
wersytetu Wrocławskiego, Wrocław 1987.
E. Kolczyk, M. Malicka, Materiały pomocnicze do nauczania Logo w szkole
średniej, Wydawnictwo Uniwersytetu Wrocławskiego, Wrocław 1988.
S. Waligórski, Programowanie w języku Logo, WNT, Warszawa 1990.
I
I
Literatura
297
M. Borzęcki, Programowanie od podstaw w ćwiczeniach i zadaniach z języka
Logo, PROSET, Gdańsk 1992.
Standardowa wersja języka Pascal jest opisana w:
H. Iglewski, J. Madey, S. Matwin, Pascal, WNT, Warszawa 1986.
Zainteresowanych szczegółowymi informacjami o języku i systemie Turbo Pa-
scal odsyłamy do opracowania:
J. Szczepkowicz, Turbo Pascal 5.0 z przykładami konstrukcji oprogramowania
podstawowego, WNT, Warszawa 1990.
Następująca książka zawiera m.in. opis systemu dBASE, którego kolejne po-
lecenia są wprowadzane na przykładzie bazy obejmującej dane o zwierzętach ży-
jących w ogrodzie zoologicznym:
T. Mykowiecki, dBase, FoxBase bazy danych, WNT, Warszawa 1992.
Brak jest książki, która zawierałaby opisy metod numerycznych dostosowane
do wiadomości z matematyki na poziomie szkoły średniej. Możemy polecić jedynie
w miarę elementarny wykład z tej dziedziny w podręczniku akademickim:
G. Dahlquist, A. Bjórk, Metody numeryczne, PWN, Warszawa 1983.
Podstawowym opracowaniem o projektowaniu algorytmów i ich złożoności,
które może stanowić uzupełnienie i rozszerzenie rozważań zamieszczonych w rozdz.
7, jest:
A.V. Aho, J.E. Hopcroft, J.D. Ullman, Projektowanie i analiza algorytmów
komputerowych, PWN, Warszwa 1983.
Polecamy także ciekawe książki o różnorodnych metodach konstruowania al-
gorytmów, doboru struktur danych i programowania:
L. Banachowski, A. Kreczmar. Elementy analizy algorytmów, WNT, Warszawa
1982.
E.W. Dijkstra, Umiejętność programowania, WNT, wyd. 2, Warszawa 1985.
N. Wirth, Algorytmy+struktury danych=programy, WNT, Warszawa 1980.
Nie wymieniliśmy żadnych opracowań (z wyjątkiem odnoszących się do sy-
stemu AC-Logo), będących jedynie leksykonami systemów oprogramowania, które
wykorzystujemy w opracowaniach EL Zawierają one bowiem najczęściej opisy
tych systemów w postaci listy haseł, a pozbawione są uporządkowania materiału
zagadnieniami lub głębszą myślą przewodnią. Czasem zmuszeni jesteśmy jednak
sięgnąć po takie leksykony - ich wybór pozostawiamy do indywidualnego uznania
Czytelnika.
Skorowidz
Abak 19
abakus 19
AC-Logo 10, 70
Ada, Lovelace 24
adres 272
bezwzględny 281
komórki 272
pusty (NIL) 147
w pamięci 147
względny 281
akapit 262, 268
al-Chorezmi 20
algorytm 9, 17, 20, 107, 189
Euklidesa 20, 125, 132, 225
Newtona-Raphsona 289
niestabilny 198
optymalny 231
porządkowania, bąbelkowy 236
, koszykowy 248
, naiwny 236
przez scalanie 238
stabilny 198
, złożoność obliczeniowa 226
argument funkcji 78
wyrażenia 78
arkusz kalkulacyjny 12, 271
arytmetyka ^-cyfrowa 193
arytmometr 35
asembler 60
atrybut 37
kroju pisma 253
Babbage, Charles 22
bajt 34
baza danych 158
dBASE 11, 179
dBASE III 179
, ochrona 177
bit 32
znaku 33
blok arkusza 278
tekstu 262
błąd bezwzględny 192
błąd kwadratury 211
względny 193
bufor 262
Całkowanie numeryczne 211
cecha 191
ChiWriter 251
ciąg Fibonacciego 155
Coloss 27
cyfra znacząca 199
cykl rozkazowy 36
Dane 17, 20
dBASE 11, 179
definicja
funkcji 79, 121
procedury 73, 111
stałej 134
typu 134
deklaracja pakietu 113
zmiennej 114
dobroć przybliżenia funkcji 206
druk proporcjonalny 268
drukarka 37
drzewo binarne 104, 242
kartotek 48
, korzeń 242
, krawędź 242
obliczeń 242, 246
Pitagorasa 104
, poziom 244
, wierzchołek końcowy 242, 246
, wierzchołek pośredni 242, 246
, wysokość 243
dyrektywa 110, 208
dysk bieżący 50
elastyczny 37
stały 37
dyskietka 37
dywan Sierpińskiego 90
EDVAC 28
edytor ChiWriter 251
, konfigurowanie 268
Skorowidz
299
edytor TAG 11, 251
tekstów ASCII 252
ekran monitora 37
użytkownika 110
ENIAC 28
Enigma 26
Euklides 20
Format 137, 144
wyświetlania 277
formatowanie 47, 63
tekstu 262
formuła 272
funkcja 78
rekurencyjna 132
standardowa 137, 190
warunkowa 287
Głośnik 38
grafika żółwia 10, 71
Hollerith, Herman 24
IBM PC 9
iloraz różnicowy 204
indeks 133
informacja 17
informatyka 17
instrukcja iteracyjna 72
powtarzania 72, 116, 119, 120
przypisania 95, 117
pusta 111
warunkowa 88, 115
wiążąca 146
wyboru 141
złożona 116
interpolacja 203
interpretator 72
Jednostka 71
sterująca 35
język AC-Logo 10, 70
algorytmiczny 60
Logo 10, 70
Pascal 11, 107
programowania 60
symboliczny 60
język Turbo Pascal 11, 107
wewnętrzny 60
justowanie tekstu 256
Karta graficzna 37
perforowana 24, 25
kartoteka 48, 50
katalog 48
klawiatura 37
numeryczna 42
klawisz funkcyjny 43
wyboru 61
klucz 49, 167
wyszukiwania 167, 235
kod ASCII 31
uzupełnieniowy 34, 66
kodowanie 31
kolejka 153
komenda 45
komentarz 83, 110
komórka 272
bieżąca 275
komputer 17
IBM PC 9
krój pisma 253
kursor 37, 274
wyboru 61
kwadratura 211
Simpsona 213
trapezów 211
Leibniz, Gottfried Wilhelm 21
licznik rozkazów 36
liczydło 19
lista 80, 93, 147, 148, 153
Logo 10, 70
Łamanie tekstu 268
Makrowywolanie 269
mantysa 191
, denormalizacja 223
, normalizacja 222
maszyna analityczna 24
Coloss 27
EDVAC 28
ENIAC 28
300
Skorowidz
maszyna Pascalina 21
różnicowa 22
Turinga 25
matryca znaków 37
Mazovia 44, 263
metoda iteracyjna 214, 216
Newtona 216
od-lewej-do-prawej 246
różnicowa 22
zstępująca 128
miara odległości 207
minimum 231
moduł klawiatury 39
pomocniczy 42
monitor 37
motyw wzoru 86
mózg elektronowy 29
MS-DOS 10, 45
mysz 38
Nadmiar zmiennopozycyjny 192
nagłówek funkcji 79, 122
procedury 73, 111
programu 108
napis 109, 272
nazwa 73, 108
Neper, John 20
Neumann, von, John 28
neurokomputer 30
niedomiar zmiennopozycyjny 192
niezmiennik 74
Obliczenia równoległe 29
szeregowe 29
odczyt 47
oferta (menu) 61, 276
okno 61, 258
operacja klawiszowa 42, 256
operator 78
dosłowności 80
oprogramowanie przyjazne 265
Pakiet 113
pałeczki Nepera 21
pamięć 34
, adres 34
pamięć buforowa 35
obrazu 37
operacyjna 35
, pojemność 34
RAM 35
ROM 35
stała 35
wewnętrzna 35
zewnętrzna 36
parametr 72
aktualny 77, 129
formalny 77, 126, 129
przekazywany przez wartość 129
przekazywany przez zmienną 129
party ej a dysku 47
Pascal 11, 107
Pascal, Blaise 21
Pascalina 21
permutacja 235, 247
pętla 119
nieskończona 123
piksel 37
?plik 45, 159
aktywny 181
bazy danych 180
, dostęp sekwencyjny 159
, drukowanie 57, 164
fizyczny 159
, kasowanie 59
, kopiowanie 56
, scalanie 56
tekstowy 159
, wyświetlanie 57, 164
, zmiana nazwy 59
płatek Kocha 104
podstawa reprezentacji 32
pole argumentów 36
operacji 36
rekordu 142, 144, 158
polskie litery 257
porządek łeksykograficzny 234
słownikowy 234
porządkowanie 234
w miejscu 237
pracochłonność algorytmu 225
procedura pierwotna 78
Skorowidz
301
procedura rekurencyjna 88, 131
standardowa 78, 109
z wartością 78
procesor centralny 35
numeryczny 208
tekstu 251
program 45
główny 111
usługowy 271
programowanie 17
strukturalne 128
przewijanie tekstu 260
Quattro Pro 12, 271
QWERTY 38, 39
Redagowanie tekstu 250
rejestr 35
górny 40
Rejewski, Marian 27 .
rekord 142, 158
bieżący 181
z wariantami 170, 171
rekurencja 88
, zależność 240
reprezentacja liczby
stałopozycyjna 191
zmiennopozycyjna 191
rozdzielczość ekranu 37
rozkaz 36
rozmiar pola 180
rozwinięcie liczby 32
równanie algebraiczne 219
Scalanie ciągów liczb 229
plików 56
schemat Homera 195, 196
Schickard, Wilhelm 21
separator 73, 109
Shannon, Claude 27
silnia 242
składowanie okresowe 266
słowo 93
kluczowe 109
maszynowe 34
soroban 19
sortowanie 234, 284
specyfikacja problemu 107
stabilność algorytmu 198
stała 134
status edytora 256
Stern, Abraham 22
struktura danych 93, 133
superkomputer 242
system AC-Logo 62, 70
baz danych 175
dBase 11, 179
operacyjny 45
MS-DOS 45
system pozycyjny binarny 21, 32
dwójkowy 21, 32
dziesiętny 31
system Quattro Pro 12, 271
TeX252
TP 11, 62
Turbo Pascal 11, 62
szablon arkusza 273
Ścieżka dostępu 50
Tablica 133
tabulator 41
TAG 11, 251
tekst ASCII 252
, blok 262
, edytor 251
, formatowanie 262
, justowanie 256
, łamanie 268
, procesor 251
, przetwarzanie 251, 256
, przewijanie 260
, redagowanie 251
TeX252
tłumienie błędów zaokrągleń 203
tom dyskowy 47
TP 11, 62
translator 60
interpretator 60
kompilator 60
treść funkcji 79
procedury 73
302
Skorowidz
trójkąt Pascala 21
tryb pracy, graficzny 37
tekstowy 37
Turbo Pascal 11, 107
Turing, Alan 25
twarda spacja 257
typ 114
całkowity 114, 191
logiczny 121
napisowy 126
rekordowy 142
rzeczywisty 134, 191
tablicowy 133
wskazywany 147
wskaźnikowy 147
wyliczeniowy 139
znakowy 121
Układ dziesiętny 31
urządzenie zewnętrzne 36
ustalanie wzorca druku 253
Warstwa edytora TAG 254
hierarchii tekstu 254
redagowania tekstu 254
wyboru plików 254
wartownik 160
warunek 89
węzły interpolacji 203
kwadratury 211
widzenie tunelowe 264
wielomian Czebyszewa 223
interpolacyjny 203
Newtona 203
wiersz stanu 62, 277
wprowadzania danych 277
wskaźnik 147
współczynniki interpolacji 204
kwadratury 211
wykres 285
kołowy 287
słupkowy 285
wyniki 20
wyrażenie 78
arytmetyczne 78, 118, 272
logiczne 89, 115, 118, 121
wysuw pionowy 252
względna dokładność komputera 193
wzór 272
rekurencyjny 195
Zadanie numeryczne 189
źle uwarunkowane 190, 201
zakładka 260
zależność rekurencyjna 196, 240
zaokrąglenie 191
ząbek 252
zegar 38
zlecenie 48
wewnętrzne 49
zewnętrzne 49
złożoność obliczeniowa algorytmu 225
pesymistyczna 243
złożony wzór Simpsona 213
trapezów 211
zmienna 95, 114
dynamiczna 147
globalna 122
lokalna 122
znaki diakrytyczne 257
znormalizowana postać liczby 191
Zuse, Konrad 27
Żółw 71
J
WYDAWNICTWO NAUKOWE PWN
Wydanie III zmienione
Arkuszy druk. 19
Druk ukończono w październiku 1993 r.
Skład i łamanie Autorzy
Druk i oprawa: Rzeszowskie Zakłady Graficzne,
Rzeszów, ul płk. L. Lisa-Kuli 19
Zam. 1985/93
Księgarnie promocyjne PWN, w których można kupić i zamówić
wszystkie publikacje naszego wydawnictwa:
BIAŁYSTOK
Księgarnia, ul. Lipowa 43
15-424 Biatystok
Księgarnia ORPAN
ul. Świętojańska 13
15-082 Białystok
BIELSKO-BIAŁA
Księgarnia "Oświata"
ul. 11 Listopada 33
43-300 Bielsko-Biala
BYDGOSZCZ
Księgarnia "Współczesna"
ul. Gdańska 5
85-005 Bydgoszcz
CZĘSTOCHOWA
Księgarnia "Antykwariat"
Al. N.M.P. 18
42-200 Częstochowa
GDAŃSK
"Księgarnia Naukowa"
ul. Grunwaldzka 111/113
80-244 Gdańsk
Księgarnia Publikacji
Naukowych"Libra"
ul. Wita Stwosza 55
80-308 Gdańsk
GDYNIA
Księgarnia "Książnica"
ul. Władysława IV 61
81-384 Gdynia
GLIWICE
Księgarnia "Mercurius"
ul. Konstytucji 146
44-100 Gliwice
KATOWICE
Księgarnia ORPAN
ul. Bankowa 11
40-007 Katowice
Księgarnia Powszechna
ul. 3 Maja 13
40-096 Katowice
KIELCE
Księgarnia "Naukowa"
ul. Buczka 19/25
25-536 Kielce
KOSZALIN
Księgarnia "Naukowa"
Rynek Staromiejski 2
75-007 Koszalin
KRAKÓW
Księgarnia "Skarbnica"
Os. Centrum C bl. 1
31-929 Kraków
Księgarnia "Techniczna"
ul. Podwale 4
31-118 Kraków
Księgarnia "Elefant"
RZESZÓW
ul. Podwale 6
Księgarnia nr 208
31-118 Kraków
ul. Dąbrowskiego 58a
Księgarnia ORPAN
35-036 Rzeszów
ul. Św. Marka 22
Księgarnia Szkolno-
31-020 Kraków
Pedagogiczna
LUBLIN
ul. Kościuszki 3
Księgarnia Współczesna
35-100 Rzeszów
Aleje Racławickie 26
SIEDLCE
20 -037 Lublin
Księgarnia "Współczesna"
Księgarnia Techniczna
ul. Pitsudskiego 68
Krakowskie Przedmieście 39
08-110 Siedlce
20-076 Lublin
Księgarnia ORPAN
ul. Marii Sktodowskiej-Curie 5
20 -031 Lublin
SŁUPSK
Księgarnia "Ratuszowa"
ul. Filmowa 5
Księgarnia "Naukowo-Techniczna"
76-200 Słupsk
ul. Nadbystrzycka 36
SZCZECIN
20 -618 Lublin
Księgarnia "Naukowa"
ŁÓDŹ
ul. Wyzwolenia 12/14
Księgarnia PWN
70-555 Szczecin
ul. Więckowskiego 13
TORUŃ
90-721 Łódź
Księgarnia
Księgarnia Akademicka
ul. Szeroka 46
ul. Narutowicza 50
87-100 Toruń
90-135 Łódź
Księgarnia "Eureka"
ul. Pitsudskiego 12
90-330 Łódź
WARSZAWA
Księgarnia PWN
ul. Miodowa 10
Księgarnia Naukowa
ul. Piotrkowska 102a
00-251 Warszawa
Główna Księgarnia Naukowa
90-004 Łódź
im. Bolesława Prusa
Księgarnia "Ethos"
ul. Piotrkowska 11
Krakowskie Przedmieście 7
00-068 Warszawa
90-406 Łódź
Księgarnia ORPAN
Pałac Kultury i Nauki
OPOLE
00-901 Warszawa
Księgarnia "Omega"
Główna Księgarnia Techniczna
Rynek 19
ul. Świętokrzyska 14
45-015 Opole
00-050 Warszawa
PIŁA
Księgarnia Fundacji Bibliotekom
Księgarnia
Polskim
ul. 14 Lutego 2
ul. Marszałkowska 74
64-920 Piła
00-524 Warszawa
POZNAŃ
Księgarnia Naukowa
Księgarnia Wydawnictwa Bellona
im. St. Żeromskiego
Al. Solidarności 119
Ossolineum
00-897 Warszawa
al. Marcinkowskiego 30
Księgarnia Uniwersytecka Libra
61-745 Poznań
Krakowskie Przedmieście 24
Księgarnia ORPAN
00-927 Warszawa
ul. Mielżyńskiego 27/29
61-725 Poznań
Księgarnia Uniwresytecka
"Unimarket"
Księgarnia Studencka
ul. Rakowiecka 41
02-521 Warszawa
ul. Zwierzyniecka 7
ZIELONA GÓRA
60-586 PoznańKsięgarnia
Księgarnia Naukowa
ul. Gwarna 13
Pod Filarami 3
61-702 Poznań
65-068 Zielona Góra
Wyszukiwarka
Podobne podstrony:
J Kossecki, Elementy wojny informacyjnej
Informacje uzupełniające Projektowanie elementów oporowych przenoszących siłę poziomą w stopach słup
Elementy wymagan informatyczne
Podstawy Informatyki Elementarz
Teoria i metodologia nauki o informacji
option extended valid elements
plan nauczania technik informatyk wersja 1
t informatyk12[01] 02 101
informatyka w prawnicza testy
Wyk6 ORBITA GPS Podstawowe informacje
Informacja komputerowa
Podstawowe informacje o Rybnie
Christmas elementary
więcej podobnych podstron