How to sort some elements and leave others in Java?

BIGJOHN :

I'm looking to sort some elements within an array but exclude others.

For a simple example, an array containing integers, I would like to sort the odd numbers but leave the even where they are.

So far I have the following:

public class MyClass {
    public static void main(String args[]) {
        int temp;
        int array[] = {5, 3, 2, 8, 1, 4};

        int[] sortedArray = new int[array.length];
        for (int j = 0; j < array.length - 1; j++) {
            for (int x = 0; x < array.length - 1; x++) {
                if (array[x] > array[x + 1] && array[x] % 2 != 0 && array[x + 1] % 2 !=0) {
                    temp = array[x];
                    array[x] = array[x + 1];
                    array[x + 1] = temp;
                    sortedArray = array;
                }
            }
        }
        for (int i: sortedArray) {
            System.out.println(i);
        }

    }
}

Given integer array: 5, 3, 2, 8, 1, 4

Output of the code: 3, 5, 2, 8, 1, 4

Expected output: 1, 3, 2, 8, 5, 4

Can't quite figure out the logic needed for the scenario in which a lower odd number comes before an even number within the original array.

GhostCat salutes Monica C. :

A simple brute force solution:

  • iterate the input array, and retrieve all odd numbers
  • collect the odd numbers in a new, smaller array
  • sort that array
  • now walk the initial array again: whenever you find a odd number, you pick the "next" entry from the odd array

The above is probably not the optimal solution (because of wasting memory on a second array, and spending time copying forth/back values) - but it should be super easy to write down and test.

Theoretically, you can also do that "in place". Meaning: you could create a class that wraps around an array of int - but that provides a view to its users that only shows an array of the odd ints.

Example implementation (thanks to Daniel Foerster):

public static int[] sortFiltered(int[] src, IntPredicate predicate) {
  int[] filtered = IntStream.of(src).filter(predicate).sorted().toArray();
  int[] dst = new int[src.length];
  for (int i = 0, j = 0; i < src.length; i++) {
    dst[i] = predicate.test(src[i]) ? filtered[j++] : src[i];
  }
  return dst;
}

Invocation with a filter for odd numbers:

sortFiltered(array, (n) -> n % 2 != 0);

As you can see this algorithm doesn’t depend on a particular predicate or array/list type. But as it uses IntStream and Lambda Expressions, it requires Java 8 or newer.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=429559&siteId=1