2015-11-18 11 views
5

Czy istnieje jedno rozwiązanie liniowe (lub proste bez pętli) do sortowania wektora według jego nieparzystych i nieparzystych wskaźników? Przykład:Sortuj wektor według indeksów parzystych i nieparzystych. C++

long entries[] = {0,1,2,10,11}; // indices 0 1 2 3 4 
std::vector<long> vExample(entries, entries + sizeof(entries)/sizeof(long)); 

vExample.sortEvenOdd(vExample.begin(),vExample.end()); // magic one liner I wish existed... 

for (int i = 0; i < vExample.size(); i++) 
{ 
    std::cout << vExample[i] << " "; 
} 

Teraz chciałbym mieć następujący wynik:

0 2 11 1 10 // corresponding to indices 0 2 4 1 3 
+2

użyj 'std :: end (wpisy)' zamiast długiego wyrażenia obliczając go – Slava

+2

to również działa: 'std :: vector vPrzykład {0,1,2,10,11}' – anatolyg

+1

Jeśli możesz użyć Boost, [' boost.strided'] (http://www.boost.org/doc/libs/1_55_0/libs/range/doc/html/range/reference/adaptors/reference/strided.html) to wszystko, czego potrzebujesz. W ten sposób nie musiałbyś nawet zmieniać kolejności wektora, co mogłoby poprawić wydajność. –

Odpowiedz

4

Próbowałam zrobić prawdziwe jeden liner:

std::stable_partition(std::begin(input), std::end(input), 
         [&input](int const& a){return 0==((&a-&input[0])%2);}); 

A oto pełny program:

#include <algorithm> 
#include <iostream> 
#include <vector> 

int main() { 
    std::vector<int> input {0,1,2,10,11}; 

    std::stable_partition(std::begin(input), std::end(input), 
         [&input](int const& a){return 0==((&a-&input[0])%2);}); 

    for (auto v : input) 
    std::cout << v << " "; 
} 

Ok wiem, że działa tylko z tego powodu, że zastosowania wektorowe ciągły zestaw elementów i cała sprawa jest brudna ... Ale jest to jedna liniówka, o którą prosi OP i nie wymaga niczego dodatkowego, jak zwiększenie ...

-1

Co trzeba to stable_partition. Zdefiniuj predykat, który sprawdza, czy indeks używa nawet modulo 2, i dobrze ci pójść.

+0

'stable_partition' działa przez wykonywanie zamiany; czy zmieniłoby się to w momencie zmiany indeksu elementu? – anatolyg

+2

Czy możesz podać przykład tego predykatu? –

+0

Ta odpowiedź jest dość niekompletna, nie jest jasne, jak to zrobić z 'stable_partition'. –

1

To nie jest jeden liner ale dość blisko:

long entries[] = {0,1,2,10,11}; // indices 0 1 2 3 4 
std::vector<long> vExample; 
for(bool flag : { true, false }) { 
    auto cond = [&flag](long) { flag = !flag; return !flag; }; 
    std::copy_if(std::begin(entries), std::end(entries), std::back_inserter(vExample), cond); 
} 
1

Jeśli można użyć Boost to dość zwięzły:

#include <boost/range/adaptor/strided.hpp> 
#include <boost/range/adaptor/sliced.hpp> 
#include <boost/range/algorithm_ext/push_back.hpp> 
#include <iostream> 
#include <vector> 

int main() { 
    using namespace boost::adaptors; 

    std::vector<int> input {0,1,2,10,11}; 
    std::vector<int> partitioned; 

    boost::push_back(partitioned, input | strided(2)); 
    boost::push_back(partitioned, input | sliced(1, input.size()) | strided(2)); 

    for (auto v : partitioned) 
     std::cout << v << " "; 
} 

Można oczywiście zawinąć że w funkcji, aby uzyskać jedna linijka w kodzie wywołującym. Live

Powiązane problemy