2015-11-18 20 views
5

Esiste una soluzione (o una semplice soluzione loop-free) per ordinare un vettore in base agli indici pari e dispari? Esempio:Ordina vettore con indici pari e dispari. 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] << " "; 
} 

Ora mi piacerebbe avere il seguente output:

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

usa 'std :: end (entries)' invece di long expression calcolandolo – Slava

+2

funziona anche: 'std :: vector vEsempio {0,1,2,10,11}' – anatolyg

+1

Se puoi usare Boost, [' boost.strided'] (http://www.boost.org/doc/libs/1_55_0/libs/range/doc/html/range/reference/adaptors/reference/strided.html) è tutto ciò che serve. In questo modo non avresti nemmeno bisogno di riordinare il vettore, il che potrebbe aiutare le prestazioni. –

risposta

4

ho cercato di fare un vero e proprio uno di linea:

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

Ed ecco il programma completo:

#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 lo so, funziona per la sola ragione che usi vettore una serie contigua di elementi e l'intera faccenda è sporca ... Ma per quello è un one liner come richiesto dall'OP e non richiede nulla in più come boost ...

-1

Quello che vi serve è stable_partition. Definisci un predicato che controlla se l'indice utilizza persino il modulo 2 e sei pronto per partire.

+0

'stable_partition' funziona facendo swap; diventerebbe confuso quando l'indice di un elemento cambia? – anatolyg

+2

Puoi fare un esempio di questo predicato? –

+0

Questa risposta è abbastanza incompleta, non è affatto chiaro come farlo con 'stable_partition'. –

1

Questo non è uno di linea, ma abbastanza vicino:

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

Se è possibile utilizzare Boost, questo è abbastanza conciso:

#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 << " "; 
} 

Ovviamente si può avvolgere che in una funzione per ottenere un un liner nel codice di chiamata. Live

Problemi correlati