2015-11-18 12 views
5

Gibt es eine Lösung mit einem Liner (oder einer einfachen Schleife), um einen Vektor nach seinen geraden und ungeraden Indizes zu sortieren? Beispiel:Sortiert Vektor nach geraden und ungeraden Indizes. 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] << " "; 
} 

Nun möchte Ich mag die folgende Ausgabe haben:

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

benutze 'std :: end (entries)' anstelle von long expression berechnend – Slava

+2

das funktioniert auch: 'std :: vector vBeispiel {0,1,2,10,11}' – anatolyg

+1

Wenn du Boost benutzen kannst, [' boost.strided'] (http://www.boost.org/doc/libs/1_55_0/libs/range/doc/html/range/reference/adaptors/reference/strided.html) ist alles was Sie brauchen. Auf diese Weise müssten Sie den Vektor nicht wirklich neu ordnen, was die Leistung verbessern könnte. –

Antwort

4

Ich habe versucht, ein echten Einzeiler zu tun:

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

Und hier ist das volle Programm:

#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 ich weiß, es funktioniert aus dem einzigen Grunde, dass Vektor-Anwendungen eine zusammenhängende Reihe von Gegenständen und das ganze Ding ist schmutzig ... Aber das ist ein One-Liner wie vom OP gefragt und es braucht nichts extra wie Boost ...

-1

Was Sie brauchen, ist stable_partition. Definieren Sie ein Prädikat, das überprüft, ob der Index sogar modulo 2 verwendet, und Sie sind gut zu gehen.

+0

'stable_partition' arbeitet mit Swaps; würde es verwirrt werden, wenn sich der Index eines Elements ändert? – anatolyg

+2

Können Sie ein Beispiel für dieses Prädikat geben? –

+0

Diese Antwort ist ziemlich unvollständig, es ist gar nicht klar, wie man das mit 'stable_partition' macht. –

1

Dies ist kein Motto, aber ziemlich nah dran:

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

Wenn Sie Boost-verwenden können, ist dies ziemlich prägnant:

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

Sie natürlich, dass in einer Funktion wickeln kann eine bekommen ein Liner im aufrufenden Code. Live