Blog (55)
Komentarze (1.1k)
Recenzje (0)
@arlidPASCAL jako mały "pomocnik"

PASCAL jako mały "pomocnik"

13.02.2012 16:50

Witajcie. Nie jestem programistą, żadnych zawodowcem czy ekspertem, staram się czegoś nauczyć, bo kto wie kiedy mi się to może przydać. Ale o czym będzie wpis?

Mianowicie ostatnio napisał do mnie kolega, ze jego syn dostał dość prostą, lecz żmudną prace domową. Mianowicie w zadaniu dane było kilkanaście ciągów i należało:

  • policzyć sumę elementów ciągu i ich iloczyn
  • posortować ciąg rosnąco i malejąco
  • podać skrajne elementu ciągu
  • obliczyć średnią arytmetyczną elementów ciągu
  • podać ilość elementów ciągu
  • podać największy element ciągu i jego położenie

Jako, że przykładów w zadaniu było sporo spytał mnie czy nie da się tego "uprościć" w arkuszu kalkulacyjnym czy w inny sposób. Pomyślałem o Pascalu. No więc mają założenia postanowiłem coś naskrobać. Oczywiście z pewnością nie jest to ekstra, bezbłędny i pozbawiony wad kod, ale nie był pisany na dłuższa metę. Co ważne działa, pomógł i po krotce powinien wyjaśnić co i jak – może się komuś przyda.

Co trzeba zrobić

Założyłem, że elementy ciągu będą umieszczone w tablicy jednowymiarowej. Jako, że nie są to zaawansowane rzeczy tablica ma maksymalnie 100 pozycji. No więc trzeba to zadeklarować: Nie zapominamy o słowie Program i nazwie programu na początku:

Program zadania;

const
max=100;

type
tablica=array[1..max]of longint;

No dobrze. Znając założenia wiem, ze będę potrzebował policzyć: sumę, iloczyn, ilość liczb, średnią arytmetyczną,posortować ciąg rosnąco i malejąco oraz znaleźć i podać miejsce i wartość elementu maksymalnego. Żeby się nie pogubić postanowiłem dla każdej z tych czynności napisać procedurę. No to pograj muzyko..

Ekhem.. zapomniałbym, przecież wpierw musimy naszej liczby wprowadzić.

procedure wypisz;

begin
for b:=1 to ilosc_liczb do

write(t<b>,', ');
writeln;

end

Wprowadzenie danych


procedure wprowadz;

begin
for b:=1 to ilosc_liczb do

begin
write('a',b,' = ');
readln(t<b>);
end;
end;

Jak widać zmienna sterująca pętla jest zmienna "b". Zmienna "ilosc_liczb" jest zmienną przechowująca ilość liczb w ciągu, wprowadza ją użytkownik.

Wypisanie wprowadzonych liczb

Aby sprawdzić czy dobrze wprowadziliśmy ciąg, warto go wyświetlić dla użytkownika

procedure wypisz;
begin
for b:=1 to ilosc_liczb do
write(t<b>,', ');
writeln;
end;

Ponownie pętla for lecz tym razem wypisująca liczby podane przez uzytkownika, czyli nasz ciąg.

Suma elementów

Jako, że trzeba policzyć sume elementów..

procedure suma;
var
suma:longint;
begin
suma:=0;
for b:=1 to ilosc_liczb do
suma:=suma+t<b>;
writeln('Suma elementów ciągu to: ',suma);
end;

Na początku zakładamy, że nasza suma równa jest 0 (bo przecież tak jest). Sumę zapiszemy do zmiennej o tej samej nazwie, zmiennej "suma". Analizując fragment tego kodu widać, że jest to odwołanie do samej siebie i dodanie kolejnego elementu ciągu aż do elementu ostatniego "ilosc_liczb".

Średnia arytmetyczna

Skoro mamy już sumę, zajmijmy się średnią. Jest to odrobinę zmodyfikowana procedura sumy

procedure srednia;
var
suma:longint;
srednia:real;
begin
suma:=0;
for b:=1 to ilosc_liczb do
suma:=suma+t<b>;
srednia:=suma/ilosc_liczb;
writeln('Średnia arytmetyczna wprowadzonych liczb to: ',srednia:3);
end;

Nie jest to mocno skomplikowane, po prostu podzieliliśmy sumę przez ilość wprwadzonych liczb - odpowiednio zmienne "suma" i "ilosc_liczb".

Iloczyn elementów

procedure iloczyn;
var
iloczyn:longint;
begin
iloczyn:=1;
for b:=1 to ilosc_liczb do
iloczyn:=iloczyn*t<b>;
writeln('Iloczyn elementów ciągu to: ',iloczyn);
end;

Nasz iloczyn na początku nie może być rowny 0, gdyż wiadomo że cokolwiek pomnożone przez 0 daje 0, więc nasz pierwszy iloczyn jest liczbą równą 1. Nastepnie postępujemy analogicznie jak przy sumie, odwołując się do poprzedniego iloczynu.

Element największy

procedure najwiekszy_element;
begin
i_max:=1;
max_el:=t[i_max];
for b:=1 to ilosc_liczb do
if t<b>>max_el then
begin
i_max:=b;
max_el:=t[i_max];
end;
writeln('Element największy to: ',max_el,' a jego położenie to: a',i_max);
end;

Na początku przyjmujemy, że naszym największym elementem jest element 1 – by mieć do czego sie odwołac. "i_max" oznacza maksymalne położenie (indeks) elementu maksymalnego a "max_el" oznacza wartość tego elementu. Instrukcja if zawarta w pętli for (tak by przejrzeć wszystkie elementy) sprawdza czy jakiś element jest większy od 1, jeżeli tak, podmienia zmienną "i_max" na połozenie nowego największego elementu czyniąc to samo z jego wartością, czyli zmienną "max_el"

Sortowanie

procedure sortowanie;
begin
zamiana:=true;
while zamiana do
begin
zamiana:=false;
for b:=1 to ilosc_liczb-1 do
if t<b>>t[b+1] then
begin
pom:=t<b>;
t<b>:=t[b+1];
t[b+1]:=pom;
zamiana:=true;
end;
end;
end;

W sortowaniu użylem algorytmu sortowania babelkowego, polegającego na porównywaniu kolejno par liczb. Zmienna "zamiana" sprawdza czy w ciągu została dokonana jakaś zamiana, bo przecież liczby mogły być ustawione w odpowiedniej kolejności – rosnąco. Dlaczego pierwsza zamiana ma wartośc true? Otóz dlatego, by dostać się do pętli while, po dostaniu się do pętli while uznajemy, ze ciąg jest ustawiony odpowiednio. iloscliczb-1, dlaczego mniej jeden? Otóż dlatego, iż par jest o 1 mniej od ilości liczb w ciągu. Mając na przykład ciąg 1, 2, 3, 4 mamy następujące pary: 12, 23, 34, czyli ilosc_liczb-1. Instrukcja warunkowa if sprawdza czy element i jest większy od elementu po nim nastepującym, jeżeli tak – zamienia je miejscami (do tego celu potrzebna jest zmienna "pom"). Jeżeli wystąpiła choć jedna zamiana zmienna zamiana przyjmuje wartość true i proces się powtarza, az ciąg będzie ustawiony w kolejności rosnącej.

No dobrze, a jak zrobić żeby było odwrotnie? Otóz nie musimy pisać oddzielnej procedury dla sortowania ciągu, Po prostu jeżli mamy ciąg w kolejności rosnącej, wypisany odwrotnie da kolejnośc malejącą, skorzystamy z tego pisząc procedurę wypisywania liczb w odwrotnej kolejności

procedure wypisz_odwrotnie;
begin
for b:=ilosc_liczb downto 1 do
write(t<b>,', ');
writeln;
end;

Niech zabłysną gwiazdki

By tekst się nie zlewał po wyświetleniu postanowiłem upakować to w jakby to ująć "boxy" . Tytuły boxów maja wyglądać nastepująco:

****************************************************** TYTUŁ ******************************************************

procedure gwiazdki (znak:char;slowo:string;ile:byte);
begin
writeln;
for b:=1 to ile do
write(znak);
writeln;
writeln(slowo);
for b:=1 to ile do
write(znak);
writeln;
writeln;
end;

znak:char;slowo:string;ile:byte to parametry formalne procedury. Pierwszy określa jaki znak będzie oddzielał zawartośc (w przykładzie "*"), drugi podaje tytuł boxu, natomiast trzeci długośc zmiennej znak.

Po zakończeniu psania procedur warto przejrzeć listę zmiennych, tutaj nie były jeszcze deklarowane. Zróbmy to:

var
ilosc_liczb,b:integer;
t:tablica;
zamiana:boolean;
pom,max_el,i_max:integer;

Co dalej?

Mając procedury zabierzmy się do napisania "ciała" programu. Rozpoczynamy od słowa begin


begin

repeat
Write('Podaj ilość liczb jaką chcesz wpisać ');
readln(ilosc_liczb);
until (ilosc_liczb>0);

Repeat sprawdza, czy nie podaliśmy przypadkiem jako ilości liczb w ciągu liczby ujemnej.

Wywołujemy zmienne:

wprowadz;
writeln;

Po wprowadzeniu przez użytkownika liczb program wykona resztę pracy za nas:

gwiazdki('*','STATYSTYKA',45);

Pierwszy parater przy wywoływaniu procedur gwiazdki zostaje "podstawiony" za zmienną "znak", drugi za zmienną "slowo", a trzeci za zmienną "ile" w parametrach formalnych procedury "gwiazdki".

writeln('Twój ciąg liczb to: ');
wypisz;
writeln('Ilosc liczb w ciągu: ',ilosc_liczb);
writeln('Elementy skarjne ciągu to: ',t[1],' oraz ',t[ilosc_liczb]);
najwiekszy_element;
sortowanie;

writeln('Liczby jakie podałeś w kolejności rosnącej to: ');
wypisz;

writeln('Liczby jakie podałeś w kolejności malejącej to: ');
wypisz_odwrotnie;

gwiazdki('*','OBLICZENIA',45);
srednia;
suma;
iloczyn;
writeln;

readln;
end.

Cały kod programu wygląda tak:


Program zadania;

const
max=100;

type
tablica=array[1..max]of longint;

var
ilosc_liczb,b:integer;
t:tablica;
zamiana:boolean;
pom,max_el,i_max:integer;

procedure wprowadz;
begin
for b:=1 to ilosc_liczb do
begin
write('a',b,' = ');
readln(t<b>);
end;
end;

procedure wypisz;
begin
for b:=1 to ilosc_liczb do
write(t<b>,', ');

writeln;
end;

procedure wypisz_odwrotnie;
begin
for b:=ilosc_liczb downto 1 do
write(t<b>,', ');
writeln;
end;

procedure gwiazdki (znak:char;slowo:string;ile:byte);
begin
writeln;
for b:=1 to ile do
write(znak);
writeln;
writeln(slowo);
for b:=1 to ile do
write(znak);
writeln;
writeln;
end;

procedure najwiekszy_element;
begin
i_max:=1;
max_el:=t[i_max];
for b:=1 to ilosc_liczb do
if t<b>>max_el then
begin
i_max:=i;
max_el:=t[i_max];
end;
writeln('Element największy to: ',max_el,' a jego położenie to: a',i_max);

end;

procedure suma;
var
suma:longint;
begin
suma:=0;
for b:=1 to ilosc_liczb do
suma:=suma+t<b>;
writeln('Suma elementów ciągu to: ',suma);
end;

procedure iloczyn;
var
iloczyn:longint;
begin
iloczyn:=1;
for b:=1 to ilosc_liczb do
iloczyn:=iloczyn*t<b>;
writeln('Iloczyn elementów ciągu to: ',iloczyn);
end;

procedure srednia;
var
suma:real;
srednia:real;
begin
suma:=0;
for b:=1 to ilosc_liczb do
suma:=suma+t<b>;
srednia:=suma/ilosc_liczb;
writeln('Średnia arytmetyczna wprowadzonych liczb to: ',srednia:3);

end;

procedure sortowanie;
begin
zamiana:=true;
while zamiana do
begin
zamiana:=false;
for b:=1 to ilosc_liczb-1 do
if t<b>>t[b+1] then
begin
pom:=t<b>;
t<b>:=t[b+1];
t[b+1]:=pom;
zamiana:=true;
end;
end;
end;

begin

repeat
Write('Podaj ilość liczb jaka chcesz wpisać ');
readln(ilosc_liczb);
until (ilosc_liczb>0);

wprowadz;
writeln;

gwiazdki('*','STATYSTYKA',45);
writeln('Twój ciąg liczb to: ');
wypisz;
writeln('Ilosc liczb w ciągu: ',ilosc_liczb);
writeln('Elementy skarjne ciągu to: ',t[1],' oraz ',t[ilosc_liczb]);
najwiekszy_element;
sortowanie;

writeln('Liczby jakie podałeś w kolejności rosnącej to: ');
wypisz;

writeln('Liczby jakie podałeś w kolejności malejącej to: ');
wypisz_odwrotnie;

gwiazdki('*','OBLICZENIA',45);
srednia;
suma;
iloczyn;

writeln;

readln;
end.

Nie jest to bardzo skomplikowany program i zapewne nie jeden z czytelników napisałby lepszy itd. jednak nie o tym chciałem napisac. Chciałem pokazac jak w prosty sposób można sobie pomóc.

Oczywiście każdy ma własne zdanie dotyczące danych kwestii nie zamierzam go w żaden sposób podważać, czy obrażać kogokolwiek w jakikolwiek sposób. Przepraszam także za ewentualne błędy.

Wybrane dla Ciebie
Komentarze (61)