Różnice między wybraną wersją a wersją aktualną.
Next revision | Previous revision | ||
power [2008/12/12 17:31] makabe utworzono |
power [2008/12/12 19:17] makabe |
||
---|---|---|---|
Linia 1: | Linia 1: | ||
====== Algorytm power ====== | ====== Algorytm power ====== | ||
- | Algorytm [[power]] podnosi obiekt klasy dowolnej klasy (o ile spełnia pewne wymagania) do zadanego wykładnika będącego nieujemną liczbą całkowitą. Algorytm korzysta z operatora * dlatego też, aby używać funkcji szablonowej power na własnych klasach należy przeładować operator * oraz =. | + | Algorytm [[power]] podnosi obiekt dowolnej klasy (o ile spełnia pewne wymagania) do zadanego wykładnika będącego nieujemną liczbą całkowitą. Algorytm korzysta z operatora *, dlatego też, aby używać funkcji szablonowej power na własnych klasach należy przeładować operatory * oraz =. |
===== Nagłówek ===== | ===== Nagłówek ===== | ||
Linia 28: | Linia 28: | ||
power(T x, Integer n) zwraca wartość x * x .... * x, gdzie x jest powtórzone n razy. Kiedy n = 0, wartość zwracana wynosi identity_element(multiplies<T>()). | power(T x, Integer n) zwraca wartość x * x .... * x, gdzie x jest powtórzone n razy. Kiedy n = 0, wartość zwracana wynosi identity_element(multiplies<T>()). | ||
- | Druga wersja (power(T x, Integer n, MonoidOperation op) )jest podobna do pierwszej. Różnica polega na tym iż zamiast operacji * ( multiplies<T> ) wykonywana jest operacja op. Kiedy n = 0 funkcja zwraca identity_element(op). Obie funkcje należy zdefiniować, tworząc np. funktor oraz przeładowując identity_element(). | + | Druga wersja (power(T x, Integer n, MonoidOperation op) )jest podobna do pierwszej. Różnica polega na tym iż zamiast operacji * ( multiplies<T> ) wykonywana jest operacja op. Kiedy n = 0 funkcja zwraca identity_element(op). Obie funkcje należy zdefiniować, tworząc np. funktor oraz przeładowując identity_element(). (patrzy przykład poniżej) |
===== Działanie ===== | ===== Działanie ===== | ||
Linia 37: | Linia 37: | ||
===== Przykład użycia ===== | ===== Przykład użycia ===== | ||
- | na obiektach klas wbudowanych: | + | ===Na obiektach klas wbudowanych:=== |
<code cpp> | <code cpp> | ||
int main() { | int main() { | ||
Linia 44: | Linia 44: | ||
</code> | </code> | ||
- | na obiektach klas zdefiniowanych przez użytkownika: | + | ===Na obiektach klasy zdefiniowanej przez użytkownika:=== |
<code cpp> | <code cpp> | ||
Linia 78: | Linia 78: | ||
cout <<czwarta << "\n"; | cout <<czwarta << "\n"; | ||
} | } | ||
+ | </code> | ||
+ | |||
+ | ===Szablon klasy macierz:=== | ||
+ | |||
+ | |||
+ | <code cpp> | ||
+ | //definicja szablonu klasy macierzy kwadratowej ktora za parametr przyjmuje rozmiar tablicy | ||
+ | template <int rozmiar> | ||
+ | class macierz | ||
+ | { | ||
+ | private: | ||
+ | int rodzaj; // 0 identycznosciowa dla operacji dodawania; 1 identycznosciowa dla operacji mnozenia | ||
+ | float tablica[rozmiar][rozmiar]; | ||
+ | |||
+ | public: | ||
+ | //destruktor | ||
+ | ~macierz(void){}; | ||
+ | //konstruktor bezargumentowy inicjuje tablice zerami | ||
+ | macierz(void) | ||
+ | { | ||
+ | for( int i = 0; i < rozmiar; i++) | ||
+ | { | ||
+ | for (int j = 0; j < rozmiar; j++) | ||
+ | { | ||
+ | tablica[i][j] = 0.0; | ||
+ | } | ||
+ | } | ||
+ | }; | ||
+ | //konstruktor kopiujacy | ||
+ | macierz(const macierz& M) | ||
+ | { | ||
+ | rodzaj = M.rodzaj; | ||
+ | for( int i = 0; i < rozmiar; i++) | ||
+ | { | ||
+ | for (int j = 0; j < rozmiar; j++) | ||
+ | { | ||
+ | tablica[i][j] = M.tablica[i][j]; | ||
+ | } | ||
+ | } | ||
+ | //*this = M; | ||
+ | }; | ||
+ | //konstruktor przyjmujący argument klasy int pozwalający tworzyć macierz jednostkową: macierz<rozmiar>(1) | ||
+ | //kontruktor ten tworzy macierz wypelniona zerami oprocz przekatnej gdzie znajduja sie jedynki | ||
+ | //niezbedny dla wlasciwego dzialania operacji power ktora dla zerowego wykladnika zwraca wartosc __T(0) gdzie __T jest obiektem klasy dla ktorej wywolany zostal algorym power | ||
+ | macierz(int x ) | ||
+ | { | ||
+ | rodzaj = x; | ||
+ | for( int i = 0; i < rozmiar; i++) | ||
+ | { | ||
+ | for (int j = 0; j < rozmiar; j++) | ||
+ | { | ||
+ | if( i == j) | ||
+ | tablica[i][j] = (float)rodzaj; | ||
+ | else | ||
+ | tablica[i][j] = 0; | ||
+ | } | ||
+ | } | ||
+ | }; | ||
+ | //przeladowany operator przypisania niezbedny dla poprawnego dzialania algoryty power, ktory wykorzystuje przypisanie wczasie wykonywania iloczynow czesciowych | ||
+ | macierz& operator=( const macierz& M) | ||
+ | { | ||
+ | rodzaj = M.rodzaj; | ||
+ | for( int i = 0; i < rozmiar; i++) | ||
+ | { | ||
+ | for (int j = 0; j < rozmiar; j++) | ||
+ | { | ||
+ | tablica[i][j] = M.tablica[i][j]; | ||
+ | } | ||
+ | } | ||
+ | return *this; | ||
+ | }; | ||
+ | //przeladowany operator mnozenia niezbedny dla poprawnego dzialania algorytmu power(T x, Integer n) | ||
+ | //w algorytmie (T x, Integer n, MonoidOperation op) sami mozemy zdefiniowac ktora operacja ma byc wykonywana na obiekcie x klasy T | ||
+ | macierz operator*( const macierz& M) const | ||
+ | { | ||
+ | macierz<rozmiar> temp; | ||
+ | for( int i = 0; i < rozmiar; i++) | ||
+ | { | ||
+ | for (int j = 0; j < rozmiar; j++) | ||
+ | { | ||
+ | for (int k = 0; k < rozmiar; k++) | ||
+ | temp.tablica[i][j] += tablica[i][k] * M.tablica[k][j]; | ||
+ | } | ||
+ | } | ||
+ | return temp; | ||
+ | }; | ||
+ | //przeladowany operator dodwania - przydatny przy testowaniu klasy | ||
+ | macierz operator+( const macierz& M) const | ||
+ | { | ||
+ | macierz<rozmiar> temp; | ||
+ | for( int i = 0; i < rozmiar; i++) | ||
+ | { | ||
+ | for (int j = 0; j < rozmiar; j++) | ||
+ | { | ||
+ | temp.tablica[i][j] = tablica[i][j] + M.tablica[i][j]; | ||
+ | } | ||
+ | } | ||
+ | return temp; | ||
+ | }; | ||
+ | //przeladowany operator na klasie ostream; sluzy do wypisania wyniku; przydatny przy testowaniu | ||
+ | friend ostream& operator<<(ostream& wy, const macierz& M) | ||
+ | { | ||
+ | for( int i = 0; i < rozmiar; i++) | ||
+ | { | ||
+ | for (int j = 0; j < rozmiar; j++) | ||
+ | { | ||
+ | wy << M.tablica[i][j] << "\t"; | ||
+ | } | ||
+ | wy << "\n"; | ||
+ | } | ||
+ | return wy; | ||
+ | }; | ||
+ | //metoda klasy sluzaca do ustawiania wartosci w tablicy | ||
+ | //x oraz y sa z zakresu 1.. rozmiar - konwencja bardziej naturalna | ||
+ | void wstaw(int x, int y, float wartosc) | ||
+ | { | ||
+ | if ( ( x > 0 ) && ( x <= rozmiar ) && ( y > 0 ) && ( y <= rozmiar ) ) | ||
+ | tablica[x-1][y-1] = wartosc; | ||
+ | }; | ||
+ | //macierz& operator+=( const macierz &); | ||
+ | //macierz& operator*=( const macierz &); | ||
+ | }; | ||
+ | |||
+ | //funktor - klasa definiujaca operator mnozenia dla klasy macierz. | ||
+ | //wlasciwie jest tutaj wykorzystany operator * zdefiniowany wewnatrz klasy | ||
+ | //ale mozna utworzyc wlasna metode mnozenia, np bardziej efektywna gdybysmy uzywali specjalnego rodzaju klas ipt. i latwo podmieniać w wywolaniu algorytmu power | ||
+ | template <int rozmiar> | ||
+ | struct mnozenie //: public binary_function<macierz<rozmiar>, macierz<rozmiar>, macierz<rozmiar>> | ||
+ | { | ||
+ | macierz<rozmiar> operator()(const macierz<rozmiar>& x, const macierz<rozmiar>& y) const | ||
+ | { | ||
+ | return x * y; | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | //przeladowana funkcja zwracajaca element identycznosciowy dla mnozenia macierzy | ||
+ | //tak jak wyzej mozna przeladowac ja wiele razy w zaleznosci od operacji mnozenia | ||
+ | template <int rozmiar> | ||
+ | macierz<rozmiar> identity_element(mnozenie<rozmiar>) { | ||
+ | return macierz<rozmiar>(1); | ||
+ | }; | ||
</code> | </code> |