Reordering array elements

Mar 9, 2021 at 6:55am
Hi, I am a rookie when it comes to C++ and would appreciate your insight, so I can go up on the learning curve.

I am trying to write a function that reorders the elements of an array where the odd numbers are to the left, in their initial relative order, whereas the even numbers are to the right, and in reverse order.
For example {13, 6, 87, 12, 45, 14} will output {13, 87, 45, 14, 12, 6}

I couldn't come up with straightforward logic, so I wonder if there is a way to put the odd values in a new temporary array, which can later be passed onto the main (and similarly a separate temp array for the even numbers).

I would appreciate your advice.
Mar 9, 2021 at 7:03am
Well the first question is, can you tell the difference between even and odd in code?

Your idea of using two temporary arrays seems very reasonable, give it a go.
Mar 9, 2021 at 8:23am
I would recommend to use std::vector instead of arrays.
You could use std::copy_if to copy the odd numbers into a new vector, the same for even numbers. Finally you add these 2 vectors together.
Mar 9, 2021 at 10:52am
With foo/bar being std::vector:
1
2
3
4
...
  std::copy_if (foo.begin(), foo.end(), bar.begin(), [](int i){return i & 1;} );
  std::copy_if (foo.begin(), foo.end(), bar.rbegin(), [](int i){return !(i & 1);} );
...
Mar 9, 2021 at 4:10pm
@salem c, good question - yes, that I can tell - using %2 and determining if it is == 0 or not

@ coder777, your suggestion seems very straightforward, but I am taking a class, and the requirement is to follow the book (and copy_if hasn't been taught yet) ... which opens a lot of other questions as to whether I should be taking this class to start with
Mar 9, 2021 at 8:19pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <vector>
using namespace std;

int main()
{
   vector<int> A = { 13, 6, 87, 12, 45, 14 };
   vector<int> B( A.size() );
   int odd = 0, even = A.size() - 1;
   for ( int e : A )
   {
      if ( e % 2 ) B[odd++ ] = e;
      else         B[even--] = e;
   }
   for ( int e : B ) cout << e << " ";
}


13 87 45 14 12 6
Mar 10, 2021 at 8:11am
whether I should be taking this class to start with
Well, that depends on your current knowledge. It is unlikely that copy_if(...) is taught at the very beginner base.

copy_if(...) can be easily converted into a loop:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int foo[] = ...
const int size = sizeof(foo) / sizeof(*foo);
int bar[size];
int odd = 0;
int even = size - 1;
for(int i = 0; i < size; ++i)
{
  if(i & 1) // or i % 2
  {
    bar[odd] = foo[i]; // 1. copy_if
    ++odd;
  }
  else // 2. copy_if
  {
    bar[even] = foo[i];
    --even;
  }
}
As you can see, it's similar to lastchance solution.
Mar 10, 2021 at 8:20am
whether I should be taking this class to start with

Well it depends what you want. If you want to learn C++ the hard way then go ahead.
If you want to learn modern C++ - which is much easier - then look for sth. else.

Mar 10, 2021 at 11:25am
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <algorithm>

const size_t maxnum {20};

void reorder(int foo[], size_t sz)
{
	int bar[maxnum] {};
	size_t odd {}, even {sz - 1};

	for (size_t i = 0; i < sz; ++i)
		if (foo[i] % 2)
			bar[odd++] = foo[i];
		else
			bar[even--] = foo[i];

	for (size_t e = 0; e < sz; ++e)
		foo[e] = bar[e];
}

int main()
{
	int foo[] {13, 6, 87, 12, 45, 14};
	const size_t sz {std::min(sizeof(foo) / sizeof(*foo), maxnum)};

	reorder(foo, sz);

	for (size_t e = 0; e < sz; ++e)
		std::cout << foo[e] << ' ';

	std::cout << '\n';
}


Which with the given numbers displays the expected:


13 87 45 14 12 6

Mar 13, 2021 at 8:28pm
Thank you all for your help and advice.

Learning is a process and it is great to be able to source from your knowledge and experience.
Topic archived. No new replies allowed.