简体   繁体   中英

How to seperate even and odd numbers in the same array?

How would I separate even and odd integers in an array with order preserved ?

Modifications must be in place and the return is a void , and can only use built in methods.

An example would be:

{4, 5, 8, 16, 45, 12, 67, 13} -> {4, 8, 16, 12, 5, 45, 67, 13}

Explanation

You can easily solve this with one iteration, remembering the index of the current border and swapping elements.

So for your example, the process will be:

{ 4, 5, 8, 16, 45, 12, 67, 13 } // swap 4 with 4
  ^

{ 4, 5, 8, 16, 45, 12, 67, 13 }
     ^

{ 4, 8, 5, 16, 45, 12, 67, 13 } // swap 5 with 8
        ^

{ 4, 8, 16, 5, 45, 12, 67, 13 } // swap 5 with 16
            ^

{ 4, 8, 16, 12, 45, 5, 67, 13 } // swap 5 with 12
                 ^

Where the ^ shows the current border index, which is always one ahead of the even values, pointing at the index where you want to swap the next even value to.


First draft

Here is the code for that:

int borderIndex = 0;
for (int i = 0; i < values.length; i++) {
    int value = values[i];
    if (value % 2 == 0) {
        // swap
        values[i] = values[borderIndex];
        values[borderIndex] = value;
        borderIndex++;
    }
}

Preserving order

Now, this solution already preserves the order of the even numbers out of the box. But if you pay close attention you see that it does not preserve order of the odd values. It goes wrong as soon as you have multiple odd values after each other before an even value, like

..., 5, 45, 12, ...

because it will then swap 5 with 12 resulting in 12, 45, 5 instead of 12, 5, 45 .

Even worse when there are multiple odd values:

..., 5, 7, 9, 11, 12, ...

resulting in 12, 7, 9, 11, 5 .

In order to fix this, we have to not just swap 5 with the even value 12 but actually swap all the way back to 5 . So:

swap 12 with 11
swap 12 with 9
swap 12 with 7
swap 12 with 5

basically shifting down 12 from right to left, until it stands right in front of 5 .

We can do so easily with a simple loop that moves from 12 (at i ) to 5 (at borderIndex ):

int borderIndex = 0;
for (int i = 0; i < values.length; i++) {
    int value = values[i];
    if (value % 2 == 0) {
        // swap from i to borderIndex
        for (int j = i; j > borderIndex; j--) {
            values[j] = values[j - 1];
            values[j - 1] = value;
        }
        borderIndex++;
    }
}

You can also do it like this. In this case your sorting them on their inherent nature as opposed to their relationship to each other.

Integer [] arr = {4, 5, 8, 16, 45, 12, 67, 13};
Arrays.sort(arr, Comparator.comparing(a->a % 2));
System.out.println(Arrays.toString(arr));

prints

[4, 8, 16, 12, 5, 45, 67, 13]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM