====== Algorytm partition ======
Dla podanego zakresu iteratorów algorytm partition ustawia wszystkie elementy, które spełniają podany predykat, przed elementami, ktore go nie spełniają. Algorytm nie musi zachowywać względnej kolejności elementów w kontenerze. Aby uzyskać funkcjonalność //std::partition// przy zachowaniu względnej kolejności elementów, należy sięgnąć do //std::stable_partition//.
===== Deklaracja =====
w pliku nagłówkowym algorithm:
template
ForwardIterator partition ( ForwardIterator first,
ForwardIterator last, Predicate pred );
===== Parametry =====
* **first, last** - iteratory wskazujące na zakres elementów, które mają ulec podziałowi. Iterator last wskazuje jeden element za ostatnim, ktory ma ulec przetwarzaniu.
* **pred** - funkcja lub obiekt funkcyjny (z przeciążonym operatorem()), będący predykatem dla podziału elementów. Elementy kontenera, które spełniają predykat, zostaną ustawione na początku kontenera, na który wskazują iteratory first i last. Elementy kontenera niespełniające predykatu zostaną ustawione w kontenerze w drugiej kolejności.
===== Zwracana wartość =====
Iterator na kolejny element za ostatnim, który spełniał podany predykat.
===== Wymagania na parametryzowane typy =====
* //ForwardIterator// posiada funkcjonalność iteratora jednokierunkowego
* //Predicate// udostępnia jednoargumentowy operator()
* Typ wartości dla klasy //BidirectionalIterator// podlega konwersji do typu argumentu operatora() dla klasy //Predicate//
===== Złożoność =====
Algorytm partition() dokonuje najwyżej (first-last)/2 zamian elementów i aplikuje podany predykat dokladnie first-last razy.
===== Przykład użycia =====
Poniżej przykład użycia zawarty również w pliku partition.cpp:
#include // std::partition
#include // std::deque
#include // std::unary_function
#include // std::cout
#include // std::ostream_iterator
//klasa predykatowa, dziedzicząca z std::unary_function, przeciążająca operator()
template
struct is_even : public std::unary_function
{
bool operator()(const Arg& arg1) const { //sprawdza, czy argument wywołania jest parzysty
return (arg1 % 2) == 0;
}
};
//funkcja predykatowa
template
bool is_odd(const Arg& arg1){ //sprawdza, czy argument wywołania jest nieparzysty
return (arg1 % 2) == 1;
}
int main (int, char**) {
typedef std::deque Deque;
typedef std::ostream_iterator Iter;
// Utworzenie kolejki za pomocą tablicy elentów typu int
const Deque::value_type a[] = { 1, 2, 3, 4, 5,
6, 7, 8, 9, 10 };
Deque d1 (a + 0, a + sizeof a / sizeof *a);
Deque d2 (d1);
Deque::iterator boundary_even; //iterator do przechowywania zwracanej wartości
// Wyswietlenie pierwotnych wartosci
std::cout << "Niespartycjonowany kontener: \n";
std::copy (d1.begin(), d1.end(), Iter(std::cout, " "));
std::cout << std::endl;
//Wyjście:
//1 2 3 4 5 6 7 8 9 10
// Dzielenie za pomocą std::partition na elementy parzyste i nieparzyste
boundary_even = std::partition (d1.begin(), d1.end(), is_even()); //wywołanie funkcji z użyciem predykatowego obiektu funkcyjnego
//W tym miejscu boundary_even wskazuje na pierwszy element, który nie spełniał predykatu is_even
std::partition (d2.begin(), d2.end(), is_odd); //wywołanie funkcji z podaniem funkcji predykatowej
// Wypisanie podzielonego kontenera
std::cout << "Spartycjonowane kontenery: \n";
std::copy (d1.begin (),d1.end(), Iter(std::cout, " "));
std::cout << "\n";
std::copy (d2.begin (),d2.end(), Iter(std::cout, " "));
std::cout << std::endl;
//Wyjście:
//10 2 8 4 6 5 7 3 9 1
//1 9 3 7 5 6 4 8 2 10
std::cout << "\n Elementy parzyste: \n";
std::copy (d1.begin (),boundary_even, Iter(std::cout, " "));
//Wyjście:
//10 2 8 4 6
std::cout << "\n Elementy nieparzyste: \n";
std::copy (boundary_even, d1.end(), Iter(std::cout, " "));
//Wyjście:
//5 7 3 9 1
return 0;
}