Convert an array, so that odd numbers are in the first half, even numbers on the second half.

Oct 21, 2020 at 9:48am
Example:
Input:
8
1 2 3 4 5 6 7 8
Output:
1 3 5 7 2 4 6 8

It is necessary to use pointers

I know my code is not correct, how can I make it right?
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
  #include <iostream>
using namespace std;
void myfunction(int* n, int* arr) {
	unsigned int counter = 0, counter2 = 0;
	int* arr2 = new int[*n];
	int b = (*n / 2)+1;
	while (counter<*n) {
		if (((*(arr+counter)) % 2) != 0) {
			*(arr2+counter) = *(arr + counter);
		}
		else {
			*(arr2+ b + counter2) = *(arr+counter);
			++counter2;
		}
		++counter;
	}
	for (int i = 0; i < *n; i++) {
		cout << *(arr2+i) << " ";
	}
	return;
}
int main() {
	int arr[100], n;
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> arr[i];
	}
	myfunction(&n, arr);
}
Oct 21, 2020 at 10:55am
Convert an array, so that odd numbers are in the first half, even numbers on the second half


There's nothing stated here about keeping the order of numbers or sorting etc. So consider using pointer:

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <utility>	// For swap
using namespace std;

void partition(int *arr, int n)
{
	for (auto last = arr + n; arr != last; ++arr) {
		while (*arr % 2)
			if (++arr == last)
				return;

		do {
			if (arr == --last)
				return;

		} while (*last % 2 == 0);

		swap(*arr, *last);
	}
}

int main()
{
	int arr[100], n;

	cout << "How many numbers? ";
	cin >> n;

	cout << "Enter the numbers\n";
	for (int i = 0; i < n; ++i)
		cin >> arr[i];

	cout << "\nEntered numbers are\n";
	for (int i = 0; i < n; ++i)
		cout << arr[i] << "  ";

	cout << "\n\n";

	partition(arr, n);

	cout << "Partitioned numbers are\n";

	for (int i = 0; i < n; ++i)
		cout << arr[i] << "  ";

	cout << "\n";
}



How many numbers? 8
Enter the numbers
1 2 3 4 5 6 7 8

Entered numbers are
1  2  3  4  5  6  7  8

Partitioned numbers are
1  7  3  5  4  6  2  8


Last edited on Oct 21, 2020 at 10:58am
Oct 21, 2020 at 11:24am
Decidedly not using pointers, but use a sort compare function that prefers odd over even, otherwise sorts ascending.
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
#include <iostream>
#include <algorithm>
using namespace std;

bool fn(int i, int j) {
  if( (i^j)&1 == 1 ) {
    // one is even, one is odd
    if ( (i & 1) == 1 ) return true;
    else return false;
  } else {
    return i < j;
  }
}

void myfunction(int* n, int* arr) {
  std::sort (arr, arr+*n, fn);
}

int main() {
	int arr[100], n;
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> arr[i];
	}
	myfunction(&n, arr);
	for (int i = 0; i < n; i++) {
		cout << arr[i] << " ";
	}
	cout << endl;
}
Oct 22, 2020 at 8:30am
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
33
34
35
36
37
38
39
40
#include <iostream>
using namespace std;

//==========================================================

void partition( int n, int *A )
{
   int *end = A + n, *odd = A;
   for ( int *p = A; p != end; p++ )
   {
      if ( p == odd ) odd++;
      if ( *p % 2 == 0 )
      {
         while ( odd != end && *odd % 2 == 0 ) odd++;
         if ( odd == end ) return;
         int temp = *odd;
         for ( int *pos = odd; pos != p; pos-- ) *pos = *(pos-1);
         *p = temp;
      }
   }
}

//==========================================================

void print( int n, int *A )
{
   for ( int *p = A; p != A + n; p++ ) cout << *p << ' ';
   cout << '\n';
}

//==========================================================

int main()
{
   int A[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
   int N = sizeof A / sizeof A[0];
   print( N, A );
   partition( N, A );
   print( N, A );
}


1 2 3 4 5 6 7 8 
1 3 5 7 2 4 6 8 





Or, with less copying, but needing temporary space:

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
33
34
35
36
37
#include <iostream>
using namespace std;

void partition( int n, int *A )
{
   int numOdd = 0;
   for ( int *a = A; a != A + n; a++ ) numOdd += *a % 2 == 1;
   if ( numOdd == 0 || numOdd == n ) return;

   int *Odd  = new int[numOdd];
   for ( int *o = Odd + numOdd - 1, *a = A + n - 1, *e = a; a != A - 1; a-- )
   {
      if ( *a % 2 ) *o-- = *a;
      else          *e-- = *a;
   }
   for ( int *a = A, *o = Odd; o != Odd + numOdd; ) *a++ = *o++;
   delete [] Odd ;
}

//==========================================================

void print( int n, int *A )
{
   for ( int *p = A; p != A + n; p++ ) cout << *p << ' ';
   cout << '\n';
}

//==========================================================

int main()
{
   int A[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
   int N = sizeof A / sizeof A[0];
   print( N, A );
   partition( N, A );
   print( N, A );
}

Last edited on Oct 22, 2020 at 9:04am
Oct 27, 2020 at 1:33pm
if you use a vector you can use the Standard Template Library partition algorithm.

1
2
3
4
5
6
7
8
9
10
11
12
#include <vector>
#include <algorithm>
#include <iostream>
int main()
{
    
    std::vector<int> data = { 1, 2, 3, 4, 5, 6, 7, 8 };
    std::partition(data.begin(), data.end(), [](int i){return i % 2 == 0;});
    for(int x: data){
        std::cout << x << ' ';
    }
}


This bit is a lamda expression,

[](int i){return i % 2 == 0;}

Just change the 2 to a 1 to put odd numbers first.
Topic archived. No new replies allowed.