sherin_a27
sherin_a27

Reputation: 323

How to sort array based on multiples of 3 using Java

I have an array like this one-

{1, 2, 3, 4, 5, 6}

I want to sort it in the order of multiples of 3 with remainders 0, 1 and 2. (the first group is multiples of 3, the second one is multiples of 3 with remainder 1 and the last one is multiples of 3 with remainder 2) and I want to preserve the order in which elements appear in the array. The result should be - {3, 6, 1, 4, 2, 5}

I have this code-

int current = 0;
int b = 0;
for (int i = 0; i < 3; i++) { //3 groups
    for (int j = current; j < numbers.length; j++) {
        if (numbers[j] % 3 == i) { //reminder should be 0,1 or 2
            b = numbers[j];
            numbers[j] = numbers[current];
            numbers[current] = b;
            current++;
        }
    }
}

But this code does not preserve the order in which elements appear in the array. The result I got is-

{3, 6, 1, 4, 5, 2}

But I want the result to be like {3, 6, 1, 4, 2, 5}. How can I achieve this?

Upvotes: 1

Views: 119

Answers (4)

Viktor Mellgren
Viktor Mellgren

Reputation: 4506

Using stream and comparator

int[] array = {1, 2, 3, 4, 5, 6};
List<Integer> lst = Arrays.stream(array)
  .boxed()
  .sorted(Comparator.comparingInt(o -> o % 3))
  .collect(Collectors.toList());

System.out.println(lst);

Upvotes: 1

Oboe
Oboe

Reputation: 2723

You can use an IntStream and a Comparator to sort the stream:

int[] arr = {1, 2, 3, 4, 5, 6};

int[] arrSorted = IntStream.of(arr).boxed()
        .sorted(Comparator.comparingInt(i -> i % 3))
        .mapToInt(Integer::intValue)
        .toArray();

System.out.println(Arrays.toString(arrSorted));

Output:

[3, 6, 1, 4, 2, 5]

Note: From IntStream.of() javadoc:

Returns a sequential ordered stream whose elements are the specified values.

Upvotes: 1

JANO
JANO

Reputation: 3076

I would create a new array of the same size and then place the elements in the correct order. For example like this:

int[] array = {1, 2, 3, 4, 5, 6};
int[] sorted = new int[array.length];
int counter = 0;
for (int i = 0; i < 3; i++) {
    for (int j = 0; j < array.length; j++) {
        if (array[j] % 3 == i) {
            sorted[counter] = array[j];
            counter++;
        }
    }
}
System.out.println(Arrays.toString(sorted));

Output:

[3, 6, 1, 4, 2, 5]

Alternatively, you can use Java 8 features to reduce the amount of code like this:

int[] array = {1, 2, 3, 4, 5, 6};
int[] sorted = Arrays.stream(array).boxed().sorted(Comparator.comparingInt(a -> (a % 3))).mapToInt(i -> i).toArray();

Output:

[3, 6, 1, 4, 2, 5]

Upvotes: 0

Anton Belev
Anton Belev

Reputation: 13543

In your solution you are swapping the elements in place, which shuffles them from the initial order. That's why you don't have the same ordering at the end. I'm not sure if there is another way apart from having a second array to keep the sorted elements, while at the same time iterating over the original one like so:

public static void main(String[] args) {
    int[] numbers = new int[]{1, 2, 3, 4, 5, 6};
    int[] result = new int[numbers.length];
    int b = 0;
    int current = 0;
    for (int i = 0; i < 3; i++) { //3 groups
        for (int j = 0; j < numbers.length; j++) {
            if (numbers[j] % 3 == i) { //reminder should be 0,1 or 2
                result[current] = numbers[j];
                current++;
            }
        }
    }

    System.out.println(Arrays.toString(result));
}

Output: [3, 6, 1, 4, 2, 5]

Upvotes: 1

Related Questions