1

Is there a one liner (or a simple loop-free) solution to de-interleave the odd and even entries of a vector?
Example:

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

vExample.intertwine(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 4 6 1 3 5 7
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
Daniel
  • 11,332
  • 9
  • 44
  • 72
  • That is really not what I would expect something called `intertwine()` to do ... On the other hand I don't know a better name. :) And why not just write a loop and put it inside a function? – unwind Nov 18 '15 at 16:57
  • Using stable sort algorithm with comparator doing something like `if (odd) return value; else return value*100000000` – Severin Pappadeux Nov 18 '15 at 16:57
  • See https://stackoverflow.com/q/7780279/10396 for an in-place solution. You'll have to wrap it in a one-liner yourself. – AShelly Apr 12 '22 at 04:24

4 Answers4

9

It seems like you are looking for std::partition or std::stable_partition, depending on whether you need the order of the elements preserved:

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

int main () {
    std::vector<int> vals {0,1,2,3,4,5,6,7};
    std::stable_partition(begin(vals), end(vals), [](auto i){return !(i % 2);});
    for (auto v : vals)
        std::cout << v << " ";
}

Output: 0 2 4 6 1 3 5 7. See it live.

You can of course partition by any other criterion by changing the predicate.

Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
  • Why does it work with the example vector, but not with, for example, {0,1,2,10,11}? It that case I'd expect {0,2,11,1,10}, but I get {0,2,10,1,11}. – Daniel Nov 18 '15 at 17:28
  • @dpgomez I don't quite understand your new example. As I understood your question, you want to put all even numbers in the front and all odd numbers in the back, which is what this does. If that is not what you want, please clarify the question. – Baum mit Augen Nov 18 '15 at 17:31
  • Why would you expect 10 to be partitioned as if odd? You must not have given a clear description of the problem. – Edward Strange Nov 18 '15 at 17:31
  • I would like the odd and even vector indices to be resorted. In my example the entries are identical to the indices. Is it better to edit the question or ask a new one? – Daniel Nov 18 '15 at 17:34
  • @dpgomez Aha. This is not at all how I (or anyone else afaics) understood this question. Maybe you should post a new question where you clearly ask how to partition a vector by indices. All the answers here solve the "partition based on the *entries*" problem. – Baum mit Augen Nov 18 '15 at 17:37
3
std::partition(std::begin(vExample), std::end(vExample), [](long l) { return !(l%2); });

Of course, partition has loop(s) in it.

http://en.cppreference.com/w/cpp/algorithm/partition

Edward Strange
  • 40,307
  • 7
  • 73
  • 125
  • 1
    I was writing an answer using a `for` loop along with moving the elements after looking at their indices, but this one takes the cake. One learns something everyday on SO. :) – therainmaker Nov 18 '15 at 16:58
  • caveat: `Relative order of the elements is not preserved.`. It looks like the OP wants this order preserved. – fjardon Nov 18 '15 at 17:01
0
for(int i = 0; i < vExample.size() * 2; i += 2) {
    auto value = vExample[i%vExample.size()];
    //Do whatever you want with value, print it out, etc.
    if(i == vExample.size() - 2) i++;
}
Xirema
  • 19,889
  • 4
  • 32
  • 68
0

You can use standard algorithm std::stable_partition declared in header <algorithm>. For example

#include <algorithm>

//...

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

std::stable_partition( vExample.begin(), vExample.end(), []( long x ) { return x % 2 == 0; } );

for ( long x : vExample ) std::cout << x << ' ';
std::cout << std::endl;

The output is

0 2 4 6 1 3 5 7
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335