Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort vector by even and odd indices. c++

Tags:

c++

std

vector

Is there a one liner (or a simple loop-free) solution to sort a vector by its even and odd indices? Example:

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

Now I'd like to have the following output:

0 2 11 1 10 // corresponding to indices 0 2 4 1 3
like image 850
dangom Avatar asked Nov 18 '15 18:11

dangom


3 Answers

I tried to do a real one liner:

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

And here is the full 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 I know, it works for the sole reason that vector uses a contiguous array of items and the whole thing is dirty... But for that's a one liner as asked by the OP and it doesn't require anything extra like boost...

like image 153
fjardon Avatar answered Nov 18 '22 05:11

fjardon


This is not one liner but pretty close:

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 );
}
like image 39
Slava Avatar answered Nov 18 '22 06:11

Slava


If you can use Boost, this is pretty concise:

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

You can of course wrap that in a function to get a one liner in the calling code. Live

like image 2
Baum mit Augen Avatar answered Nov 18 '22 05:11

Baum mit Augen