Materiały dodatkowe zadanie 4

Transkrypt

Materiały dodatkowe zadanie 4
Paradygmaty programowania
Programowanie generyczne w C++
Dr inż. Andrzej Grosser
Czestochowa,
2014
,
2
Spis treści
1. Zadanie 4
5
1.1. Wprowadzenie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
1.2. Wskazówki do zadania . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7
3
4
Spis treści
1. Zadanie 4
1.1. Wprowadzenie
Dzisiejsze zadanie jest dość proste do zrobienia wymagaja, jedynie (przynajmniej w
niektórych przypadkach) przygotowania odpowiedniego dla danego algorytmu funktora.
Można tutaj wyróżnić:
1. generate() - funktor nieprzyjmujacy
żadnych argumentów i zwracajacy
element
,
,
sekwencji np. (nie podaje, definicji klasy Osoba, ale latwo można ja, wydedukować):
c l a s s Gen {
public :
Osoba operator ( ) ( ) {
return Osoba ( ”Nowak ” , ”A l e k s a n d e r ” , 1 8 ) ;
}
};
// . . .
s t d : : v e c t o r <Osoba> vec ( 1 0 ) ;
s t d : : g e n e r a t e ( vec . b e g i n ( ) , vec . end ( ) , Gen ( ) ) ;
2. sort(), unique() - predykat dwuargumentowy (zwraca wartość logiczna, i pobiera
elementy sekwencji) np.:
c l a s s Pred {
public :
bool operator ( ) ( const Osoba& o1 , const Osoba& o2 ) const {
return o1 . nazwisko ( ) > o2 . nazwisko ( ) ;
}
};
// . . .
s t d : : v e c t o r <Osoba> vec ( 1 0 ) ;
// . . . Operacje na w e k t o r z e np . w c z y t y w a n i e z p l i k u
// S o r t o w a n i e
s t d : : s o r t ( vec . b e g i n ( ) , vec . end ( ) , Pred ( ) ) ;
3. remove_if(), remove_copy_if() - predykat jednoargumentowy (zwaraca wartość
logiczna, i pobiera elemnt sekwencji) np.:
c l a s s Pred2 {
5
6
1. Zadanie 4
public :
bool operator ( ) ( const Osoba& o ) const {
return o . nazwisko ( ) [ 0 ] == ’A ’ ;
}
};
// . . .
s t d : : v e c t o r <Osoba> vec ( 1 0 ) ;
// . .
// Dopiero w po l a, c z e n i u z metod a, e r a s e ( ) e l e m e n t y s a,
f i z y c z n i e usuwane
vec . e r a s e ( s t d : : r e m o v e i f ( vec . b e g i n ( ) , vec . end ( ) , Pred2 ( ) )
, vec . end ( ) ) ;
4. accumulate() - funktor dwuagrumentowy np.:
c l a s s Fun {
public :
// Prev t o p o p r z e d n i a warto ś ć z l i c z a n e j w i e l k o ś c i ,
// p r z e d u w z g l e, dnieniem b i e ż a, cego elementu
double operator ( ) ( double prev , const Osoba& o ) {
return prev + o . wiek ( ) ;
}
};
// . . .
s t d : : v e c t o r <Osoba> vec ( 1 0 ) ;
// . . .
double sum = accumulate ( vec . b e g i n ( ) , vec . end ( ) , 0 . 0 , Fun ( ) ) ;
5. transform() - wymaga funkcji dwuargumentowej lub jednoargumentowej w zależności od użytej wersji np.:
c l a s s Fun2 {
public :
int operator ( ) ( const Osoba& o ) {
return o . wiek ( ) ;
}
};
// . . .
s t d : : v e c t r o <Osoba> vec ( 1 0 ) ;
s t d : : v e c t o r <int> wiek ( 1 0 ) ;
// . . .
// Tutaj transformowana j e s t w e k t o r os ó b na w e k t o r
// z a w i e r a j a, cy t y l k o wiek os ó b ( i n t −y )
s t d : : t r a n s f o r m ( vec . b e g i n ( ) , vec . end ( ) , wiek . b e g i n ( ) , Fun2 ( ) ) ;
1.2. Wskazówki do zadania
7
Uwaga - podana lista nie wyczerpuje wszystkich możliwości, niektóre wersje algorytmów nie wymagaja, podawania funktorów, wystarcza zapewnienie dla określonego typu
stosownego operatora (np. istnieje wersja sort, dla której wystarczy dostarczyć operator
mniejszości (<), podobnie istnieje wersja unique, która korzysta z operator równości (==)
itd.). Po szczególy implementacyjne odsylam Was do dokumentacji.
1.2. Wskazówki do zadania
1. Algorym unique() podobnie jak remove_if nie usuwa fizycznie elementów, dlatego
wymagane jest polaczenie
z metoda, erase(). Do poprawnego użycia tego algorytmu
,
wymagane jest także wcześniejsze posorotwanie sekwencji (usuwa powtórzone elementy, które sasiaduj
a, ze soba).
,
,
2. Przenoszenie elementów polega na skopiowaniu ich z orginalnej sekwencji do sekwencji wynikowej a nastepnie
wymagane jest fizyczne usuniecie
elementów z oryginalnego
,
,
zasobnika. Do tego celu można użyć algorytmów remove_if i remove_copy_if - należy sobie jednak zdać sprawe,
gdyż tak
, że nazwa drugiego algorytmu jest mylaca,
,
naprawde, sluży do kopiowania elemntów, dla których predyka nie jest spelniony (musi
wykonywać odwrotność tego co dla remove if).
3. Algorytmy same nie przydziela, dodatkowej pamieci
o
, - programista musi pamietać
,
jej wcześniejszym przydzieleniu lub skorzystać z dodatkowych mechanizmów np. z
back inseretera):
v e c t o r <int> v1 ( 1 0 ) , v2 ;
copy ( v1 . b e g i n ( ) , v1 . end ( ) , b a c k i n s e r t e r ( v2 ) ) ;
W podanym powyżej przykladzie elementy sa, kopiowane z wektora v1 do wektora v2,
kolejne elementy sa, dostawiane na koniec wektora v2 - dzieki
użycia back inseretera
,
nie byl potrzebny przydzial pamieci
, dla v2 - ta metoda jest szczególnie użyteczna dla
algorytmów, dla których nie wiadomo z góry ile elementów trzeba bedzie
przenieść
,
(np. remove_copy_if()).
4. Algorytm accumulate() wymaga dolaczenia
naglówka numeric.
,

Podobne dokumenty