0

I have two solutions for this problem, but which is one is optimal?

A list of N numbers is given. The player has to arrange the numbers so that all the odd numbers of the list come after the even numbers. Write an algorithm to arrange the given list such that all the odd numbers of the list come after the even numbers.

Input

The first line of the input consists of an integer numbers, representing the size of the list(N). The second line of the input consists of N space-separated integers representing the values of the list

Output

Print N space-separated integers such that all the odd numbers of the list come after the even numbers

Example

Sample Input

8
10 98 3 33 12 22 21 11

Sample Output

10 98 12 22 3 33 21 11

Solution no1-

    #include<bits/stdc++.h>
using namespace std;

int main(){
    
    int n;
    cin>>n;
    
    int a[n];
    
    for(int i=0; i<n; i++)
      cin>>a[i];
      
    
    int p1=0, p2= n-1;
    
    while(p1 < p2){
        
        while(a[p1]%2 == 0 and p1<p2)
           p1++;
        
        while(a[p2]%2 != 0 and p1<p2)    
           p2--;
        
        if(p1 < p2){
            swap(a[p1], a[p2]);
            p1++;
            p2--;
        }
    }
    
    
    for(int i=0; i<n; i++)
     cout<<a[i]<<" ";
    
    return 0;
}

solution 2-

#include <iostream>

using namespace std;

int main()
{
    int n;
    cin>>n;
    int arr[n];

    for(int i=0;i<n;i++){
        cin>>arr[i];
    }
    
    for(int i=0;i<n;i++){
        if(arr[i]%2==0)
        cout<<arr[i]<<" ";
    }
    for(int i=0;i<n;i++){
        if(arr[i]%2!=0)
        cout<<arr[i]<<" ";
    }
    

    return 0;
}
JaMiT
  • 14,422
  • 4
  • 15
  • 31
  • 9
    Both are invalid, `cin>>n; int arr[n];` is not standard C++. – Quimby Sep 03 '21 at 17:52
  • @Quimby As of C++ 11, I'm not sure that's true. https://www.geeksforgeeks.org/variable-length-arrays-in-c-and-c/ – Joseph Larson Sep 03 '21 at 17:53
  • 3
    @JosephLarson It is true, VLAs are not supported in any version of C++. – Quimby Sep 03 '21 at 17:56
  • 2
    Clarify your definition of "optimal". Are you talking about optimal size in memory? Optimal performance? Optimal readability? Optimal robustness? Optimal ease of maintenance? Sooo many questions, so little time. – Thomas Matthews Sep 03 '21 at 17:59
  • 1
    What you might want to do is check out [std::partition](https://en.cppreference.com/w/cpp/algorithm/partition). As you can see at the probable implementation, only one loop is required. – PaulMcKenzie Sep 03 '21 at 18:04
  • @Quimby I read more carefully, and i think you're incorrect. As of C++14, not 11. I was wrong on that part. If you go to the article I linked then use the links there, you'll get to the C++14 standard here: https://isocpp.org/files/papers/N3690.pdf. Go to page 184-185. There's an EXAMPLE of passing a non-const into a function and using that as the size of an array. In the standard (top of page 185) – Joseph Larson Sep 03 '21 at 18:04
  • @JosephLarson [See this](https://godbolt.org/z/v14PdKxG1) – PaulMcKenzie Sep 03 '21 at 18:10
  • 2
    @JosephLarson Yes, N3690 contains a proposal for that, but it did not make it in the end. See [this answer](https://stackoverflow.com/a/29115882/7691729) and [this overview](https://stackoverflow.com/a/40656359/7691729). So the article just linked to incorrect, unfinished version of the standard. – Quimby Sep 03 '21 at 18:11
  • If you want to ignore the advice about `std::vector` and continue with variable length arrays you need to put hard limits on `n` because an `n` greater than about 200000 runs a significant risk of overflowing the stack on a Windows PC. Linux generally offers a larger stack so you might be able to get 4 or 8 times that. Use the `vector` so you can get a much larger array and receive errors if you try to grab too much. – user4581301 Sep 03 '21 at 18:53
  • The second is a bit better... since it does not [#include ](https://stackoverflow.com/q/31816095) which is a programming horror. – prapin Sep 03 '21 at 20:33

2 Answers2

0

I would make a few changes, but mostly follow the second example.

First, I would put in an if-statement to ensure that n is a positive number. That's just a good check to do.

Next, I wouldn't output them quite like this. I'd build a second array instead.

int inputArray[n];
int finalArray[n];
int outputIndex = 0;

... Fill inputArray like you currently fill array

for (int i = 0; i < n; ++i) {
    if (inputArray[i] % 2 == 0) {
        outputArray[outputIndex++] = inputArray[i];
    }
}

Do the second loop the same way. Then dump the outputArray.

Now, some other notes. These are stylistic, but will help you. Please use more whitespace in your code. Notice my code has spaces between operators. You're clearly young with young eyes, but good habits now will matter when you have to share code with old farts. Your scrunched-together code is really quite difficult to read and can readily hide errors. You wouldn't believe how many bugs are in code because some programmer was afraid of spaces.

Second, many programmers will tell you that optional braces shouldn't be treated as optional. Notice my if-statement has a pair of braces whereas yours don't. And if you look at how your code was formatted, you'll see that your indentation is wrong. You didn't indent your cout lines properly. This is a way errors hide. If you always use braces, evne when the language thinks they're optional, you'll have fewer bugs.

Lastly, most people will suggest you stop using fixed-length arrays and instead use vector, but as you're a new programmer, maybe you're not ready for that.

Joseph Larson
  • 8,530
  • 1
  • 19
  • 36
  • 2
    That's not C++, its still C. Since n is only available at runtime and not at compile time. In C++ you need std::vector for that. – Pepijn Kramer Sep 03 '21 at 18:01
  • 3
    Since `array[n]` is a Variable Length Array (VLA) and not supported by **Standard C++**, I recommend replacing them with `std::vector`. – Thomas Matthews Sep 03 '21 at 18:02
  • 1
    @PKramer Please go read the standard for C++ 14 page 184 to 185. https://isocpp.org/files/papers/N3690.pdf. The top of page 185 has an example of using a non-const int as the array size. But you'll notice I also told him at the end to use std::vector. – Joseph Larson Sep 03 '21 at 18:05
  • 1
    @ThomasMatthews See my comment to PKramer. – Joseph Larson Sep 03 '21 at 18:05
  • 1
    I highly recommend that new programmers use `std::vector`, since it is more foolproof than arrays. If the OP wants to use arrays, then use the dynamic memory allocation rather than VLA's. Dynamic memory allocation is very standard. – Thomas Matthews Sep 03 '21 at 18:07
  • 3
    @JosephLarson paper N3690 appears to be a pre-C++14 draft, with reference to a VLA proposal that was not accepted. VLA is not supported in the final standard. https://stackoverflow.com/questions/60566659/runtime-array-bounds-on-stack-as-per-c-draft – Drew Dormann Sep 03 '21 at 18:14
  • @JosephLarson "C" style arrays are not something I would like to teach new C++ programmers. I agree with Thomas here, arrays are the source of too many bugs, you can't return them from functions. I could have been less fierce in my comment to you though. – Pepijn Kramer Sep 03 '21 at 18:16
  • N3690 is an ugly draft that is very far from any actual C++ version. Here's a link to the various C++ drafts which are very close to an actual released standard. http://github.com/timsong-cpp/cppwp – rustyx Sep 03 '21 at 21:46
0
#include <iostream>

using namespace std;

int main()
{
    int n;
    cin >> n;
    int* arr = new int[n];
    int* odd = new int[n];
    int* even = new int[n];
    int oddIndex = 0;
    int evenIndex = 0;

    for(int i=0;i<n;i++){
        cin>>arr[i];
    }
    
    for(int i=0;i<n;i++){
        if(arr[i]%2==0)
            even[evenIndex++] = arr[i];
        else
            odd[oddIndex++] = arr[i];
    }

    for(int i=0;i<evenIndex;i++){
        cout<<even[i]<<" ";
    }

    for(int i=0;i<oddIndex;i++){
        cout<<odd[i]<<" ";
    }
    

    return 0;
}
Hossein
  • 439
  • 3
  • 9