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] (aktualna) 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> | ||