• Nie Znaleziono Wyników

16. Automat wydaje, czyli jak dynamicznie wydawać resztę

N/A
N/A
Protected

Academic year: 2022

Share "16. Automat wydaje, czyli jak dynamicznie wydawać resztę"

Copied!
10
0
0

Pełen tekst

(1)

III. P R O G R A M O W A N I E I A L G O R Y T M Y

metoda zachłanna

16. Automat wydaje, czyli jak dynamicznie wydawać resztę

N A TEJ LE K C JI:

• dowiesz się, na czym polega metoda zachłanna;

• użyjesz w programie zmiennych tablicowych.

W rzucając pieniądze do automatu z napojami, nie m usisz o dliczać dokładnej kwoty. Urządzenie sam o sumuje nominały, w ydaje towar i resztę. Jak kom puter w autom acie o blicza resztę? Czy algorytm jest skom plikow any? Opracujm y go w spólnie. Nie będzie to bardzo trudne.

16.1. Zachłannie, czyli wydajemy resztę z użyciem najmniejszej liczby nominałów

Przypom nij sobie, jak sprzedaw ca w sklepie w ydaje resztę. O czyw iście może to zrobić, używ ając dowolnych nominałów. Robi to na tyle racjonalnie, by w kasie nie zabrakło żadnego z nich.-Automat musi kierow ać się innymi kryteriam i. Nie tylko kwota musi się zgadzać, lecz także w ydaw anie m usi być optym alne, czyli z użyciem jak najm niejszej liczby wydawanych monet. Załóżm y, że ma zostać w ydana kwota 13 zł i 60 groszy z użyciem najmniejszej liczby monet (rys. 16.1.).

. r .

m

1 szt.

V . .... ____^

0 szt.

IW..________ 4 '

? 1 szt.

.. .... ..J

1 szt. ; 1 szt.

'h— _____ 4

2 szt.

...

Rys. 16.1. Optymalne wydanie reszty w kwocie 13,60 zł

Zastanów się teraz nad kwotami, które m ożna w ydaw ać za pom ocą zestawu m onet z rysunku 16.1. Je śli jest ich dostatecznie dużo, m ożesz w ydać dow olną kwotę pod warunkiem , że nie będzie ona zaw ierała pojedynczych groszy. Z tego wniosek, że dzięki odpow iednio dobranym w system ie m onetarnym nom ina­

łom, m ożna złożyć dow olną kwotę.

W ydaw anie reszty (jak na rysunku 16.1.), czyli zaczynając od największej, m oż­

liwej liczby najw yższych nominałów, nazyw am y m etodą zachłanną. Je śli prze­

analizujesz tę metodę, zapew ne dojdziesz do wniosku, że nie sprawdzi się ona dla nietypowego zestaw u nominałów. Gdybyśm y chcieli kwotę 6 złotych w ydać za pom ocą monet dwu- i pięciozłotow ych, algorytm zachłanny w ydałby najpierw

110

(2)

m onetę pięciozłotow ą, bo jej w artość m ieści się w 6. Kasjerka w sklepie w yda­

łaby trzy m onety dwuzłotowe. Ale ona nie stosuje algorytm u zachłannego.

Przystępując do opracow ania algorytm u w ydaw ania reszty m etodą zachłanną, musim y założyć, że do dyspozycji są w szystkie dostępne nom inały w odp o­

wiedniej ilości. Dla uproszczenia w przykładzie w ykorzystam y jedynie nom inały 1, 2 i 5 złotych oraz założymy, że w ydajem y resztę niezaw ierającą groszy (rys.

16.2.). W przykładow ym algorytm ie użyto następujących zmiennych:

r e s z t a - zm ienna zaw ierająca kwotę do wydania. W trakcie procesu w ydaw a­

nia zm ienia w artość na równą kwocie, która pozostała do wydania.

I i c z b a 5 , l i c z b a 2 , l i c z b a l to zm ienne, w których ostatecznie zosta­

nie zapisana liczba poszczególnych nom inałów do wydania.

START

Rys. 16.2. Przykład algorytmu wydającego resztę metodą zachłanną dla reszty wyrażo­

nej liczbą całkowitą

Algorytm nie w ym aga om ówienia. Zastanów się jednak, czy blok zaznaczony czerw oną ram ką jest konieczny do otrzym ania praw idłowego wyniku. Od tego m iejsca w artość zm iennej r e s z t a nie zm ienia się do końca działania algo­

rytmu. Może w ięc być w yśw ietlona jako liczba w ydawanych złotówek, czyli

(3)

indeks O

III. P R O G R A M O W A N I E I A L G O R Y T M Y

zm ienna l i c z b a l staje się niepotrzebna. W łaśnie dokonaliśm y weryfikacji optym aln ości kodu programu.

M odyfikacja w iąże się także ze zm ianą w bloku w yjściow ym - jako liczbę w yda­

wanych złotów ek należy w pisać w artość zm iennej reszta. Może ona m ieć w artość 0 dla parzystych kwot do w ydania lub 1 dla nieparzystych. Na tym przykładzie widać, że każdy algorytm powinien być w eryfikow any nie tylko pod kątem funkcjonalności (daje praw idłowe wyniki czy nie), lecz także pod kątem jego budow y i w ykorzystania zasobów komputera. W tym przypadku dodatkow a zm ienna spowoduje zarezerw ow anie w iększego obszaru pam ięci.

Program realizujący algorytm z rysunku 16.2. w ykorzystuje fakt, że zm ienna zadeklarow ana jako int przechow ująca w ynik dzielenia będzie zaw ierała jedynie jego czę ść całkow itą. Nie ma w ięc potrzeby korzystania z odpowiedniej funkcji ( d iv ) podającej w artość całkow itą liczby (rys. 16.3.).

1 #include <iostream>

2 #include <stdlib.h>

3

4 using namespace std;

5

6 int liczba5=0j liczba2=0, liczbal=0, reszta;

7-int main () 8 {

9 cout << "Podaj kwotę do wydania: ";

10 cin >> reszta;

11

12 liczba5=reszta/5;

13 reszta=reszta-liczba5*5;

14 liczba2=reszta/2;

15 reszta=reszta-liczba2*2;

16

17 cout << "do wydania" << endl;

18 cout << liczba5 <<" szt. pięciozłotówek" << endl;

19 cout << -liczba2 <<" szt. dwuzłotówek" << endl;

20 cout << reszta <<" szt. złotówek" << endl;

21 return 0;

22 }

Rys. 16.3. Program wydający resztę według przykładowego algorytmu zachłannego

Podaj kwotę do wydania: 23 do wydania

4 szt. pięciozłotówek 1 szt. dwuzłotówek 1 szt. złotówek

Podaj kwotę do wydania: 1 0 do wydania

2 szt. pięciozłotówek 0 szt. dwuzłotówek 0 szt. złotówek

Rys. 16.4. Wyniki działania programu wydającego resztę metodą zachłanną dla kwoty 23 złote i 10 złotych

112

(4)

Program (rys. 16.3.) będzie zaw sze w yśw ietlał liczbę w szystkich nominałów, nawet gdy nie będą używane do w ydania reszty (rys. 16.4.). Zm odyfikujm y algorytm i program.

Dzięki zastosow aniu badania w arunków można opu ścić drukow anie i o b li­

czenia dla nom inałów w iększych od pozostałej do w ydania kwoty (rys. 16.5.).

W program ie ułożonym w edług tego algorytm u zastosow ano badanie w arunków za pom ocą instrukcji i f (rys. 16.6.).

START I

Wprowadź kwotę do wydania r e s z t a

lic z b a 5 = 0 ; lic z b a 2 = 0 ; li c z b a l = 0 ;

Drukuj

“pięciozłotówki”

liczba5“szt.”

t

l i c z b a 5 = r e s z t a / 5 r e s z t a = r e s z t a - l i c z b a 5 * 5

i

NIE

r e s z t a /2 > = 0

Drukuj

“dwuzłotówki”

liczba2“szt.”

t I

TAK li c z b a 2 = r e s z t a / 2 r e s z t a = r e s z t a - l ic z b a 2 * 2

Rys. 16.5. Inne rozwiązanie algorytmu dla metody zachłannej wydawania reszty

113

(5)

III. P R O G R A M O W A N I E I A L G O R Y T M Y

1 #include <iostream>

2 #include <stdlib.h>

3

4 using namespace std;

5

6 int liezba5=0, liczba2=0, liczbal=0, reszta;

7 int main () 8 {

9 cout << "Wprowadź kwotę do wydania: ";

10 cin >> reszta;

11 cout << endl;

12 if (reszta/5>=l) 13 {

14 liczba5=reszta/5;

15 reszta=reszta-liczba5*5;

16 cout << "pięciozłotówki - " << liczba5 << " szt."<< endl;

17 >

18

19 if (reszta/2>=l) 20

{

21 liczba2-reszta/2;

22 reszta=reszta-liczba2*2;

23 cout << "dwuzłotówki - " << liczba2 << " szt.” << endl;

24 >

25

26 if (reszta==l)

27 cout << "złotówki - 1 szt.";

28

29 return 0;

30 >

Rys. 16.6. Przykładowy program realizujący algorytm z rysunku 16.5.

Wprowadź kwotę do wydania: 11 pięciozłotówki - 2 szt.

złotówki - 1 szt.

Rys. 16.7. Wynik działania programu z rysunku 16.6

16.2. Nominały w tablicach, czyli jedna zmienna, wiele wartości

W obiegu znajdują się zarówno monety, jak i banknoty. Program kom puterowy może podpow iedzieć sprzedawcy, ile i jakich nom inałów ma użyć do wydania reszty. W Polsce w obiegu są następujące nom inały banknotów: 50 0 zł, 200 zł, 10 0 zł, 50 zł, 20 zł, 10 zł oraz monet: 5 zł, 2 zł, 1 zł, 50 gr, 20 gr, 10 gr, 5 gr, 2 gr i 1 gr. Jedynie banknotem pięćsetzłotow ym nie da się wydawać reszty. Gdyby dla w szystkich pozostałych 14 nom inałów budować algorytm podobny do tego z rysunku 16.3., należałoby rozbudować go o kolejnych 11 dzieleń lub warunków.

W y d a n ie 11 złotych m eto d ą zachłanną nie przew iduje dw u zło tó w ek.

(6)

Można jednak posłużyć się tablicam i, w których zostaną zapisane w szystkie nom inały i użyć bloku warunkowego (rys. 16.8.). Spowoduje to, że algorytm po odpow iednich zm ianach w tablicy n o m i n a ł y będzie w ydawał także resztę dla nom inałów używanych na przykład w Stanach Zjednoczonych, w których używa się m onety 25 centów, a nie ma m onet o nom inałach 2 i 20 centów.

- Przypomnienie --- O dśw ież swoją w iedzę na tem at zm iennych tablicow ych. Tablica jest zm ienną, która może przechow yw ać w iele w artości. Każda pozycja tablicy jest indeksow ana (od 0 do n), to oznacza, że ma swój numer. W zw iązku z tym podczas deklaracji należy podać jej rozmiar. W C++, jeśli podczas deklaracji tablicy zostanie ona w ypełniona danymi, podawanie rozmiaru nie jest konieczne. Podobnie jak inne zm ienne tablice m uszą m ieć nazwę i określony typ danych, jakie będą przechowywały.

Przykład:

i n t t a b l ic a [ ] = { 2 0 0 0 0 , 1 0 0 0 0 ,5 0 0 0 ,2 0 0 0 ,1 0 0 0 , 5 0 0 ,2 0 0 ,1 0 0 ,5 0 ,2 0 ,1 0 ,5 ,2 ,1 } ;

lub inaczej

i n t t a b l i c a [ 1 3 ] ;

W pierw szym przypadku tablica została w ypełniona 14 danymi. W dru­

gim - ta sam a tablica musi być w ypełniana danymi w czasie realizacji pro­

gramu. O czyw iście w obu przypadkach program może w pisyw ać do nich nowe w artości. W przykładzie t a b l i c a [0] będzie m iała w artość 2 0 0 0 0 , t a b l i c a [ 4 ] 10 00, a t a b l i c a [ 8 ] to 50. Ja k widać, indeks w skazuje bezpośrednio pozycję w tablicy.

Można zadeklarow ać tablice o większej liczbie wymiarów.

Zm ienne tablicow e są nazyw ane także m acierzam i.

W róćm y do naszego zadania. Algorytm (rys. 16.8.) w zasadniczej części nadal realizuje m etodę zachłanną w ydaw ania reszty. Tym razem jednak używa do tego w szystkich m ożliw ych nominałów. W przykładow ym algorytm ie o b li­

czona liczba poszczególnych nom inałów jest drukowana tuż po obliczeniu i nie jest przechow yw ana.

Prześledźm y działanie algorytm u na przykładzie. Załóżmy, że kwota do w yda­

nia to 4 0 ,10 zł. Taką też w artość zapiszm y pod zm ienną r e s z t a .

(7)

III. P R O G R A M O W A N I E I A L G O R Y T M Y

START

Wprowadź kwotę do wydania reszta

Rys. 16.8. Przykładowy algorytm wydawania reszty metodą zachłanną używający 14 nominałów

(8)

Tab. 16.1. Analiza działania algorytmu wydawania reszty metodą zachłanną dla kwoty 40,10 zł

1 Krok Działanie W artości

1. Wprowadzenie kwoty do wydania reszta = 40.10

2. Wypełnienie tablicy nominałami nominaly[13]={200,100, 50, 20,10, 5, 2 ,1 , 0.5, 0.2, 0.1, 0.05, 0.02, 0.01}

3. Indeks tablicy - zmienna i - ustawiony na pierw szej danej tablicy

i = 0

4. Czy reszta jest już wydana reszta=40.1 * 0

kierunek - NIE 5. Czy kwota do wydania zawiera w sobie przynaj­

mniej jedną wartość nominału 200

nominaly[0]=200 40.1<nominaly[0]

kierunek - NIE 6. Indeks tablicy ustawia się na następny nominał i= 0+ l= l

7. Czy reszta jest już wydana reszta=40.1 * 0

kierunek - NIE Kroki 4, 5, 6, 7 są wykonywane do momentu, gdy i = 3

8. Reszta do wydania jest większa od 20 reszta>=nominaly[3]=20 kierunek TAK

9. Obliczanie liczby dwudziestozłotówek liczbanominalow=40.1/20=2 Nie ma części ułamkowej, ponieważ zmienna jest typu int

10. Obliczanie pozostałej kwoty po wydaniu 20 zł reszta=40,l-(20*2)=0.1 zł

11. Wydruk liczby dwudziestozłotówek Wydaj 2 x 20

12. Indeks następnego nominału i=3+l=4

13. Reszta jeszcze nie wydana reszta=0.1 * 0

kierunek - NIE Dla nominałów od 4 do 9 wartość warunku reszta>=nominaly[i] - NIE

14. i=10 0.1>=nominaly[10]=0.1

kierunek TAK

15. Obliczanie liczby dziesięciogroszówek liczbanominalow=0.1/0.1=l

16. Obliczanie pozostałej kwoty po wydaniu 2x20 zł i 10 gr

reszta=0.1-0.1*1= 0

17. Wydruk liczby dziesięciogroszówek Wydaj 1 x 0.1

18. Cała reszta wydana Warunek reszta=0 spełniony

Koniec obliczeń

(9)

’ ;c ] ) ł } r e t u r n b.

, , b ) , b - b . rej ig»p_arr*y. ;• + + ) { j”s s e _ c la s s - u s e _ a rra y (l

III. P R O G R A M O W A N I E I A L G O R Y T M Y

Realizacja algorytm u (rys. 16.8.) w języku C++ napotyka na pewne trudno­

ści. Otóż czę ść nom inałów jest m niejsza od 1. Z tej przyczyny tablicę powinno się zadeklarow ać jako zm ienną typu f l o a t . Pozostała kwota do wydania (zm ienna reszta) także musi być liczbą rzeczyw istą. Gdy do w ydania zostaje 0,01 złotego, w artość zmiennej reszta powinna w yn osić 0,01. Niestety kom ­ puter oblicza w artość zmiennej reszta z pewnym przybliżeniem , co spow o­

duje błędny wynik dla kwot do w ydania o nieparzystej liczbie groszy. W pro­

gram ie zastosujem y w ięc zaokrąglenie do setnych części złotego. W program ie (rys. 16.9.) została użyta funkcja round powodująca zaokrąglenie wyniku do . części całkowitej w sposób, który znasz z m atematyki, na przykład dla liczby 0,6 da w ynik 1, a dla 0,4 da 0. Jej użycie jest m ożliw e po dołączeniu biblio­

teki math.h. Zaokrąglenie wyniku obliczan ia reszty pozostałej do w ydania do dw óch m iejsc po przecinku realizuje linia 20.

res z ta=round(( reszta- (nominały [i] *liczbanominalow)) *100)/100;

Tablica nom inałów będzie m iała postać:

float nomin a ł y[] = { 2 0 0 , 1 0 0 , 5 0 , 2 0 , 1 0 , 5 , 2 , 1 , 0 . 5 , 0 . 2 , 0 . 1 , 0 . 0 5 , 0 . 0 2 , 0 . 0 1 } Nie ma potrzeby podawania rozmiaru tablicy w [ ], skoro podczas deklaracji w pisujem y do niej konkretne dane.

1 #include <iostream>

2 #include <stdlib.h>

3#include <math.h>

4using namespace std;

5

6int łiczbanominalow, i=0;

7float nominały[]»{200,100,50,20,10,5,2,l,0.5,0.2,0.1,0.05,0.02,0.01}, reszta;

8

9*int main()

I© {

11 cout << "Podaj kwotę do wypłacenia:

12 cin >> reszta;

13

14 cout << endl << "wydaj następujące nominały:" << endl << endl;

15 while (reszta!*©) 16 {

17 if (reszta >= nominały[i]) 18 {

19 liczbanominalow=reszta/nominaly[i];

20 reszta=round((reszta-(nominały[i]*liczbanominałow))+100)/100;

2122 cout << nominały[i] << ” zł - " << liczbanominalow << " szt." << endl;

23 >

24 i-M-;

25 )

26 return 0;

27 >

Rys. 16.9. Przykładowy program wydający resztę metodą zachłanną korzystający z wszystkich nominałów

(10)

Podaj kwotę do wypłacenia: 444.31 wydaj następujące nominały:

200 zł - 2 szt.

20 zł - 2 szt.

2 zł - 2 szt.

0.2 zł - 1 szt.

0.1 zł - 1 szt.

0.01 zł - 1 szt.

Rys. 16.10. Wynik działania programu wydającego resztę metodą zachłanną wykorzy­

stującego wszystkie nominały

ZA D A N IA DO RO ZW IĄZAN IA

1. Jak ą wartość m oże przybierać liczba wydawanych najniższych nominałów, np. 1 zł 1 gr? Uzasadnij swoją odpowiedź i podaj kilka przykładów.

2. Zmodyfikuj program z rysunku 16.3. w taki sposób, by wydawanie reszty realizowała funkcja.

Zdefiniuj ją. Efekt działania program u (wyświetlanie komunikatów) powinien pozostać bez zmian.

3. Automaty, w których można dokonać zakupów, operują najczęs'ciej nominałam i od 5 zł do 10 g ro ­ szy. Zmodyfikuj algorytm i program wydawania reszty w taki sposób, by mógł być zastosowany w takich urządzeniach.

4. Zmodyfikuj program z rysunku 16.9. w taki sposób, by m ożna było w prowadzać kwotę reszty do wydania w złotówkach, np. 34,51 zł. Sprawdź, jak dokładność wykonywania obliczeń wpływa na działanie program u dla różnych kwot w tym 34,51 zł.

5. Zmodyfikuj program wydawania reszty z wykorzystaniem wszystkich dostępnych nom inałów w USA.

PO DSUM OW ANIE LEKCJI

• M etod a z a c h ła n n a zakłada wydawanie reszty nominałam i największymi z możliwych. M ożna opra- s. 110 cować wiele algorytmów wykorzystujących metodę zachłanną, w tym także uwzględniających różne

zakresy dostępnych nominałów.

• Z m ie n n e ta b lic o w e są zmiennymi, w których można przechowywać wiele wartości. W szystkie są s. H5 tego sam ego typu, deklarowanego podczas deklaracji tablicy. Jeśli podczas deklaracji zmiennej tablico­

wej jednowymiarowej wypełnimy ją danymi, nie ma potrzeby podawania jej rozmiaru.

• Dane zapisane w zmiennej tablicowej są indeksowane numerem miejsca w tablicy. Dla tablicy jedno- S- H2 wymiarowej pierw sza ma in d e k s 0.

119

Cytaty

Powiązane dokumenty