====== Algorytmy unique, unique_copy ====== Algorytmy te znajdują się w bibliotece //algorithm//. === Nagłówek === #include ===== unique ===== template ForwardIterator unique ( ForwardIterator firstElement, ForwardIterator lastElement ); template ForwardIterator unique ( ForwardIterator firstElement, ForwardIterator lastElement, BinaryPredicate comp ); **unique ** to algorytm służący usuwaniu następujących po sobie duplikatów elementów z zakresu [ //firstElement// , //lastElement// ). //firstElement// i //lastElement// są iteratorami wskazującymi na pozycję w kontenerze ( np. lista, wektor ). Algorytm jest realizowany poprzez usuwanie wszystkich elementów identycznych z elementem bezpośrednio poprzedzającym. Porównywanie elementów odbywa się przy wykorzystaniu operatora ==. W przypadku, gdy nie jest zaimplementowany, należy podać jako trzeci argument predykat, który porównuje elementy. Powinien on zwracać //true// jeśli elementy są identyczne i //false// w przeciwnym przypadku. Zachowanie algorytmu jest następujące: template ForwardIterator unique ( ForwardIterator firstElement, ForwardIterator lastElement ) { ForwardIterator result = first; while ( ++first != last ) { if ( !( *result == *first ) ) *(++result)=*first; } return ++result; } ==== Parametry ==== * //firstElement, lastElement// - iteratory wskazujące zakres elementów na którym będzie realizowany algorytm. Zakres ten zawiera wszystkie elementy od //firstElement// do elementu poprzedzającego //lastElement//. * //comp// - binarny predykat przyjmujący 2 elemety jako argumenty i zwracający //true// jeśli oba są równe i //false// w przeciwnym przypadku. Może to być zarówno wskaźnik na funkcję, jak i wskaźnik na obiekt klasy przeciążającej //operator()//. ==== Wartość zwracana ==== Iterator wskazujący na nowy koniec sekwencji z zadanego zakresu, która nie zawiera już powtarzających się po sobie elementów. ==== Uwaga ==== Należy uwzględnić fakt, że algorytm **unique** nie zmienia wielkości kontenera, ani nie zmienia elementów położonych za nowym końcem ( ciągle są dostępne ). ==== Przykład ==== #include #include #include using namespace std; // implementacja funkcji porownujacej elementy bool comp(int i, int j) { return (i==j); } int main () { // tworzy wektory z powtarzajacymi sie po sobie elementami int myints[] = {10,20,20,20,30,30,20,20,10}; vector myvector (myints,myints+9); // 10 20 20 20 30 30 20 20 10 vector::iterator it; // PRZYKLAD UZYCIA UNIQUE Z DOMYSLNYM OPERATOREM == // użycie unique z domyslnym operatorem == it = unique (myvector.begin(), myvector.end()); // 10 20 30 20 10 30 20 20 10 // dostosowanie wielkosci myvector do zaktualizowanej liczby elementow myvector.resize( it - myvector.begin() ); // 10 20 30 20 10 // wypisanie zawartosci myvector // 10 20 30 20 10 cout << "\nunique z domyslnym operatorem==\n"; for (vector::iterator iter=myvector.begin(); iter!=myvector.end(); ++iter) cout << " " << *iter; // PRZYKLAD UZYCIA UNIQUE ZE ZDEFINIOWANA FUNKCJA POROWNUJACA ELEMENTY myvector.clear(); myvector.insert(myvector.begin(), myints, myints + 9); // 10 20 20 20 30 30 20 20 10 // uzycie unique ze zdediniowana funkcja porownujaca elementy it = unique (myvector.begin(), myvector.end(), comp); // 10 20 30 20 10 30 20 20 10 // dostosowanie wielkosci myvector do zaktualizowanej liczby elementow myvector.resize( it - myvector.begin() ); // 10 20 30 20 10 // wypisanie zawartosci myvector // 10 20 30 20 10 cout << "\n\nunique ze zdefiniowana funkcja porownujaca\n"; for (vector::iterator iter=myvector.begin(); iter!=myvector.end(); ++iter) cout << " " << *iter; cout << endl; return 0; } ===== unique_copy ===== template OutputIterator unique_copy ( InputIterator firstElement, InputIterator lastElement, OutputIterator result ); template OutputIterator unique_copy ( InputIterator firstElement, InputIterator firstElement, OutputIterator result, BinaryPredicate comp ); **unique_copy** kopiuje wartości elementów z zakresu [ //firstElement//, //lastElement// ) do zakresu, którego początek wskazuje iterator //result//, za wyjątkiem następujących po sobie duplikatów. Algorytm pomija elementy o wartościach identycznych z elementem bezpośrednio je poprzedzającym ( kopiowany jest zawsze tylko pierwszy element ze zbioru elementów identycznych ). Porównywanie elementów odbywa się przy wykorzystaniu operatora ==. W przypadku, gdy nie jest zaimplementowany, należy podać jako trzeci argument predykat, który porównuje elementy. Powinien on zwracać //true// jeśli elementy są identyczne i //false// w przeciwnym przypadku. Zachowanie algorytmu jest następujące: template ForwardIterator unique ( ForwardIterator firstElement, ForwardIterator lastElement ) { ForwardIterator result = first; while ( ++first != last ) { if ( !( *result == *first ) ) *(++result)=*first; } return ++result; } ==== Parametry ==== * //firstElement, lastElement// - iteratory wskazujące zakres elementów na którym będzie realizowany algorytm. Zakres ten zawiera wszystkie elementy od //firstElement// do elementu poprzedzającego //lastElement//. * //result// - iterator wskazujący początek zakresu, do którego ma być zapisana sekwencja elementów wyznaczona przez algorytm. * //comp// - binarny predykat przyjmujący 2 elemety jako argumenty i zwracający //true// jeśli oba są równe i //false// w przeciwnym przypadku. Może to być zarówno wskaźnik na funkcję, jak i wskaźnik na obiekt klasy przeciążającej //operator()//. ==== Wartość zwracana ==== Iterator wskazujący na koniec skopiowanego zakresu. ==== Przykład ==== #include #include #include using namespace std; // implementacja funkcji porownujacej elementy bool comp(int i, int j) { return (i==j); } int main () { // tworzy wektory z powtarzajacymi sie po sobie elementami int myints[] = {10,20,20,20,30,30,20,20,10}; vector myvector (9); // 0 0 0 0 0 0 0 0 0 vector::iterator it; // użycie unique_copy z domyslnym operatorem == it=unique_copy (myints,myints+9,myvector.begin()); // 10 20 30 20 10 0 0 0 0 // sortowanie elementow sort (myvector.begin(),it); // 10 10 20 20 30 0 0 0 0 // uzycie unique_copy ze zdediniowana funkcja porownujaca elementy it=unique_copy (myvector.begin(), it, myvector.begin(), comp); // 10 20 30 20 30 0 0 0 0 // dostosowanie wielkosci myvector1 do zaktualizowanej liczby elementow myvector.resize( it - myvector.begin() ); // 10 20 30 // wypisanie zawartosci // 10 20 30 for (vector::iterator iter=myvector.begin(); iter!=myvector.end(); ++iter) cout << " " << *iter; cout << endl; return 0; } ===== Przykładowy program ===== {{:stl_algorytmy:unique_unique_copy.cpp|}}