Problem wydawania reszty w C++ PDF Drukuj Email
Wpisał doctor   
Sobota, 08. Maj 2010 20:47

W artykule tym zajmiemy się problemem wydawania reszty.Omówimy algorytm wydawania reszty, a także przedstawimy jego implementację w C++.Zaczynamy!

Na co dzień spotykamy się z urządzeniami mającymi zaimplementowany algorytm do wydawania reszty.Są to automaty z napojami czy bankomaty.Na pozór te urządzenia są bardziej skomplikowane, niż może się wydawać.Problem wydawania reszty to zagadnienie z dziedziny algorytmiki.Problem zajmuje się kwestią wydania reszty należności ze zbioru dostępnych nominałów, przy czym ilość wydawanych monet/banknotów powinna być minimalna.Problem ten rozwiązuje się dwoma algorytmami: algorytmem zachłannym i za pomocą programowania dynamicznego.My zajmiemy się tym pierwszym.Algorytm zachłanny jest ograniczony jedną własnością: przy rozwiązywaniu problemu wydawania reszty zakładamy, że mamy nieograniczoną ilość monet i banknotów o różnych nominałach.


Na potrzeby programu wprowadzimy sobie kilka zmiennych i oznaczeń.

k - zmienna typu int, mówiąca o reszcie do wydania
x - liczba monet/banknotów, które otrzyma klient
int N[8] = {200,100,50,20,10,5,2,1}; //tablica nominałów posortowana rosnąco
int X[8] = {0,0,0,0,0,0,0,0};// każdy indeks tablicy to informacja, ile klient dostanie banknotów 1 zł, 2 zł, 5 zł itd.

Jak działa algorytm zachłanny rozwiązujący problem wydawania reszty

Na początku wprowadzamy lub wyliczamy kwotę potrzebną do wydania klientowi.Jest to nasza zmienna k.Dalej, algorytm wyszukuje największy nominał n ze zbioru nominałów ale taki, aby nie przekraczał on pozostałej kwoty do wydania.Mając taki nominał, od pozostałej kwoty do wydania k odejmujemy ten właśnie największy nominał n.Program pracuje w pętli, a więc za każdym razem jak zostanie znaleziony największy nominał do wydania, zwiększa się licznik x niosący ze sobą informację o liczbie monet/banknotów wydanych klientowi.Algorytm powinien więc znajdować minimum funkcji wydawania liczby monet/banknotów.Jako, że nasz program nie tylko podaje ile monet/banknotów dostanie z powrotem klient, ale także rozbija tę ilość na poszczególne nominały, wprowadziłem zmienną tablicową X przechowującą liczbą poszczególnych nominałów wydanych klientowi.W zmiennej tablicowej N natomiast wpisane są wszystkie dostępne nominały.Dla ułatwienia, algorytm nie uwzględnia monet mniejszych od 1 zł, a podawana kwota musi być liczbą całkowitą (int).

Tworzymy program do wydawania reszty

Na formę kładziemy 1 pole Edit służące do wprowadzania kwoty do wydania.Także 1 przycisk, do niego podpięta będzie akcja obliczania reszty.Dodatkowo w programie testowym wykorzystałem 9 kontrolek Label oraz 9 kontrolek StaticText.Zdefiniujmy dwie zmienne globalne:

int N[8] = {200,100,50,20,10,5,2,1}; //tablica nominalow posortowana rosnaco
int X[8] = {0,0,0,0,0,0,0,0};//tablica liczby nominalow każdego rodzaju wydanych w kolejnosci wg N

Algorytm programu jest następujący:

int k = Edit1->Text.ToIntDef(0);//do wydania przy kasie
int x = 0; //liczba monet do wydania

while(k>0)
{
int n = 0;//maksymalny nominal mniejszy lub rowny kwocie pozostalej do zaplaty
int ile_nominalow = ARRAYSIZE(N);//ilosc elementow tablicy N
int kolejny=-1;//bo indeksy tablicy zaczynaja sie od 0
        for(int i=0;i<ile_nominalow;++i)    //znajdowanie najwiekszego nominalu do wydania
        {//i oznacza indeks nominalu
        if( (N[i]<=k)&&(N[i]>n) )
        {
        n=N[i];
        kolejny=i;
        }
        }
k-=n;
++x;
X[kolejny]+=1;
}
Label1->Caption = x; //liczba monet/banknotow do wydania

Label2->Caption = X[0];
Label3->Caption = X[1];
Label4->Caption = X[2];
Label5->Caption = X[3];
Label6->Caption = X[4];
Label7->Caption = X[5];
Label8->Caption = X[6];
Label9->Caption = X[7];

Zrzut ekranu prezentowanego programu można zobaczyć tu, a pobrać program można tu.Zapraszam do komentowania artykułu.
Komentarze
Dodaj nowy Szukaj
+/-
Napisz komentarz
Nick:
E-mail:
 
Strona www:
Tytuł:
UBBCode:
[b] [i] [u] [url] [quote] [code] [img] 
 
 
:angry::0:confused::cheer:B):evil::silly::dry::lol::kiss::D:pinch:
:(:shock::X:side::):P:unsure::woohoo::huh::whistle:;):s
:!::?::idea::arrow:
 
Proszę wpisać kod antyspamowy widoczny na obrazku.

3.26 Copyright (C) 2008 Compojoom.com / Copyright (C) 2007 Alain Georgette / Copyright (C) 2006 Frantisek Hliva. All rights reserved."

Ostatnia aktualizacja: Sobota, 22. Maj 2010 10:19
 
 

Losowy obraz

b14.jpg

Gościmy

Naszą witrynę przegląda teraz 8 gości 




| | | |