Narzędzia użytkownika

Narzędzia witryny


inplace_merge

Różnice

Różnice między wybraną wersją a wersją aktualną.

Odnośnik do tego porównania

Both sides previous revision Previous revision
Next revision
Previous revision
inplace_merge [2009/04/03 17:27]
ornsh
inplace_merge [2009/04/03 18:25] (aktualna)
ornsh
Linia 2: Linia 2:
  
 <code cpp> <code cpp>
-template <class BidirectionalIterator>​''​+template <class BidirectionalIterator>​
 inline void inplace_merge(BidirectionalIterator first, inline void inplace_merge(BidirectionalIterator first,
                           BidirectionalIterator middle,                           BidirectionalIterator middle,
Linia 12: Linia 12:
                           BidirectionalIterator last, StrictWeakOrdering comp);                           BidirectionalIterator last, StrictWeakOrdering comp);
 </​code>​ </​code>​
 +
 +===== Opis algorytmu =====
  
 Algorytm zawarty w Standard Template Library. ​ Algorytm zawarty w Standard Template Library. ​
-Funkcja inplace_merge() łączy dwa uporządkowane rosnąco zakresy [first, middle) oraz [middle, last) w jeden zakres [first, last) uporządkowany rosnąco.  +Funkcja inplace_merge() łączy dwa uporządkowane rosnąco zakresy ​//[first, middle)// oraz //[middle, last)// w jeden zakres ​//[first, last)// uporządkowany rosnąco.  
-Algorytm jest stabilny. W pierwszej wersji funkcji do porównywania elementów używany jest operator<​ .  +Algorytm jest stabilny. W pierwszej wersji funkcji do porównywania elementów używany jest //operator< ​//.  
-W drugiej wersji możliwe jest dostarczenie własnego funktora testującego poprzedzanie elementów. Funkcja testująca pobiera 2 argumenty i zwraca wartość logiczną TRUE w przypadku, gdy pierwszy argument poprzedza drugi; jeśli zamienimy argumenty miejscami otrzymamy FALSE.+W drugiej wersji możliwe jest dostarczenie własnego funktora testującego poprzedzanie elementów. Funkcja testująca pobiera 2 argumenty i zwraca wartość logiczną ​//TRUE// w przypadku, gdy pierwszy argument poprzedza drugi; jeśli zamienimy argumenty miejscami otrzymamy ​//FALSE//. 
 + 
 +===== Złożoność ===== 
 + 
 +Złożoność pesymistyczna algorytmu to O(N log(N)). 
 + 
 +===== Nagłówek =====
  
-====Nagłówek==== 
 <code cpp>#​include <​algorithm></​code>​ <code cpp>#​include <​algorithm></​code>​
  
-====Definicja inplace_merge()==== +===== Parametry =====
-<code cpp></​code>​+
  
-====Parametry==== 
  * first - iterator wskazujący początek pierwszego zakresu  * first - iterator wskazujący początek pierwszego zakresu
  * middle - iterator wskazujący koniec pierwszego zakresu i jednocześnie początek drugiego zakresu  * middle - iterator wskazujący koniec pierwszego zakresu i jednocześnie początek drugiego zakresu
  * last - iterator wskazujący koniec drugiego zakresu  * last - iterator wskazujący koniec drugiego zakresu
-binary_pred ​- argument opcjonalny, wskaźnik na funkcję testującą poprzedzanie drugiego obiektu przez pierwszy+comp - argument opcjonalny, wskaźnik na funkcję testującą poprzedzanie drugiego obiektu przez pierwszy 
 + 
 +===== Przykłady ===== 
 + 
 + * Inicjalizacja struktur danych 
 + 
 +<code cpp> 
 +    std::​list<​int>​ container, containerDesc,​ containerDivis;​ 
 +    std::​list<​int>::​iterator it; 
 +     
 +    container.push_back(13); ​       containerDesc.push_back(13); ​       containerDivis.push_back(2); ​        
 +    container.push_back(15); ​       containerDesc.push_back(11); ​       containerDivis.push_back(8);​ 
 +    container.push_back(17); ​       containerDesc.push_back(9); ​        ​containerDivis.push_back(32);​ 
 +    container.push_back(19); ​       containerDesc.push_back(7); ​        ​containerDivis.push_back(128);​ 
 +     
 +    container.push_back(8); ​        ​containerDesc.push_back(20); ​       containerDivis.push_back(1);​ 
 +    container.push_back(10); ​       containerDesc.push_back(12); ​       containerDivis.push_back(4);​ 
 +    container.push_back(14); ​       containerDesc.push_back(8); ​        ​containerDivis.push_back(16);​ 
 +    container.push_back(18); ​       containerDesc.push_back(5); ​        ​containerDivis.push_back(64);​ 
 +    container.push_back(28); ​       containerDesc.push_back(0); ​        ​containerDivis.push_back(1024);​ 
 +</​code>​ 
 + 
 +     * Próba użycia algorytmu przy niespełnionym warunku uporządkowania jednego z zakresów 
 + 
 +zakres pierwszy: ​      13, 15, 17\\ 
 +zakres drugi: ​         19, 8, 10, 14, 18, 28\\ 
 +Na wyjściu otrzymamy niepożądaną kolejność elementów (w tym przypadku niezmienioną) 
 + 
 +<code cpp> 
 +    std::​inplace_merge(container.begin(),​ ++(++(++container.begin())),​ container.end());​ 
 +     
 +    std::cout << "wynik dzialania funkcji przy braku uporzadkowania rosnacego:"​ << std::​endl;​ 
 +    for(it = container.begin();​ it != container.end();​ ++it) 
 +             ​std::​cout << *it << " "; 
 +    std::cout << std::endl <<​std::​endl;​ 
 +</​code>​ 
 + 
 +     * Najprostsze użycie algorytmu inplace_merge tworzące jeden rosnąco posortowany zakres z dwóch oddzielnie uporządkowanych 
 + 
 +zakres pierwszy: ​      13, 15, 17, 19\\ 
 +zakres drugi: ​         8, 10, 14, 18, 28 
 + 
 +<code cpp> 
 +    std::​inplace_merge(container.begin(),​ ++(++(++(++container.begin()))),​ container.end());​ 
 +     
 +    std::cout << "​zawartosc container'​a po wykonaniu inplace_merge to:" << std::​endl;​ 
 +    for(it = container.begin();​ it != container.end();​ ++it) 
 +             ​std::​cout << *it << " "; 
 +    std::cout << std::endl <<​std::​endl;​ 
 +</​code>​ 
 + 
 +     * Wykorzystanie opcjonalnego argumentu funkcji inplace_merge() 
 + 
 +Załóżmy że chcemy uzyskać uporządkowanie malejące z dwóch malejących zakresów.\\ 
 +Do tego celu posłużę się funktorem greater<​T>​ (nagłówek:​ //#include <​functional>//​).\\ 
 +zakres pierwszy: ​      13, 11, 9, 7\\ 
 +zakres drugi: ​         20, 12, 8, 5, 0 
 + 
 +<code cpp> 
 +    std::​inplace_merge(containerDesc.begin(),​ ++(++(++(++containerDesc.begin()))),​ containerDesc.end(),​ std::​greater<​int>​());​ 
 +     
 +    std::cout << "​zawartosc containerDesc'​a po wykonaniu inplace_merge z odwroconym uporzadkowaniem to:" << std::​endl;​ 
 +    for(it = containerDesc.begin();​ it != containerDesc.end();​ ++it) 
 +             ​std::​cout << *it << " "; 
 +    std::cout << std::endl <<​std::​endl;​ 
 +</​code>​ 
 + 
 +     * Wykorzystanie opcjonalnego argumentu funkcji inplace_merge() 
 + 
 +Tym razem utworzyłem funkcję //bool divisible(int,​ int)//, która zwraca //TRUE// w przypadku gdy drugi argument jest podzielny przez pierwszy, w przeciwnym wypadku //​FALSE//​\\ 
 +funkcja zostanie wykorzystana przez inplace_merge 
 +<code cpp> 
 +/** 
 + * Funkcja testująca podzielność drugiego argumentu przez pierwszy 
 + * Zwraca TRUE w przypadku gdy drugi argument jest podzielny przez pierwszy, w przeciwnym wypadku FALSE 
 + */ 
 +const bool divisible(const int &arg1, const int &​arg2) 
 +
 +    return !(arg2 % arg1); 
 +
 +</​code>​ 
 +zakres pierwszy: ​      2, 8, 32, 128\\ 
 +zakres drugi: ​         1, 4, 16, 64, 1024 
 + 
 +<code cpp> 
 +    std::​inplace_merge(containerDivis.begin(),​ ++(++(++(++containerDivis.begin()))),​ containerDivis.end(),​ divisible);​ 
 +     
 +    std::cout << "​zawartosc containerDivis'​a po wykonaniu inplace_merge z dostarczona funkcja divisible:"​ << std::​endl;​ 
 +    for(it = containerDivis.begin();​ it != containerDivis.end();​ ++it) 
 +             ​std::​cout << *it << " "; 
 +    std::cout << std::endl <<​std::​endl;​ 
 +</​code>​ 
 + 
 +===== inplace_merge algorithm.cpp =====
  
-====Przykłady====+{{ inplace_merge algorithm.cpp }}
  
inplace_merge.1238772459.txt.gz · ostatnio zmienione: 2009/04/03 17:27 przez ornsh