1

Scenario:

I need to read an array of integers from the standard inputstream, reorder it in such a way that a prime number is always followed by two even numbers ensuring that the prime and even numbers are picked up from the array in the order in which they are present to build the prime-2even set. Any remaining numbers that can't be part of the set can be placed at the end of the array in the order in which they appear. The input(in multiple lines) and expected output(in multiple lines) as below:

Input:

8 5 9 7 8 5 4 6 8

Expected output:

5 8 4 7 6 8 9 5

Attempt:

public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    int totalElements = Integer.parseInt(scanner.nextLine());

    Integer[] integers = new Integer[totalElements];
    Integer[] primeTwoEvens = new Integer[totalElements];
    Integer[] leftOvers = new Integer[totalElements];

    for (int i = 0; i < integers.length; i++) {
        integers[i] = scanner.nextInt();
    }

    // LOGIC
    int notNullCounter = 0; // Variable to track how many elements of integers array has been set to null.
    while (notNullCounter != integers.length) { // Repeat this process until all the elements of the integers array are null.
        for (int i = 0; i < integers.length; i++) { // Iterate the integers array and check for primeTwoEvens and populate the primeTwoEvens array.
            if (integers[i] != null) { // Is the element of integers array to be processed null? If no, proceed.
                if (isPrime(integers[i])) { // Is the element of integers array prime? If yes, proceed.
                    System.out.println(integers[i] + " is prime..."); // Print statement for debugging purpose.
                    primeTwoEvens[i] = integers[i]; // Since the element of integers array is prime, add it to the primeTwoEvens array.
                    integers[i] = null; // Set this index of integers array to null.
                    notNullCounter++;   // As one element of integers array has been set to null, increment the null counter.


                    int evenCounter = 0; // Variable to track even number occurrences.
                    while (evenCounter != 2) { // Repeat this process until 2 even numbers are not found.
                        for (int j = ++i; j <= integers.length; j++) { // Iterate the remaining elements of integers array and check for next two even numbers.
                            if (isEven(integers[j])) { // Is the element of integers array even? If yes, proceed.
                                System.out.println(integers[j] + " is even..."); // Print statement for debugging purpose.
                                evenCounter++; // Since the element of integers array is even, increment the even counter.
                                primeTwoEvens[++i] = integers[j]; // Since the element of integers array is even, add it to the primeTwoEvens array as well.
                                integers[j] = null; // Set this index of integers array to null.
                                notNullCounter++; // As one element of integers array has been set to null, increment the null counter.
                            }
                        }
                    }
                } /*else { // Element is not prime.

                }*/
            }
        }
        //break;
    }// End of while

    /*System.out.println("@@@@@@@@@@@@ PRINTING THE FINAL SORTED ARRAY  @@@@@@@@@@@@");
    for (Integer integer : integers) {
    System.out.println(integer);
    }*/
}

throws me an java.lang.ArrayIndexOutOfBoundsException

Output:

5 is prime...
8 is even...
4 is even...
6 is even...
8 is even...
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 8
    at Ideone.main(Ideone.java:125)

Line 125:

if (isEven(integers[j]))

Note: I am restricted to using Java standard API and JDK 7.

How do I solve the problem and the final task?

Sandeep Chatterjee
  • 3,220
  • 9
  • 31
  • 47
  • isn't easier to just classify your numbers in 3 different list? (prime, even and non-both) and then just arrange them everytime a `primeTwoEven` occur? – Alex S. Diaz Sep 13 '15 at 05:27

2 Answers2

2

I think the previous line (before Line 125) should be

for (int j = ++i; j < integers.length; j++)

Not <=

1

You could try this:

public static void main(String[] args) {
    // Read your file (I just copy your example to an array)
    Integer[] integers = new Integer[] { 8, 5, 9, 7, 8, 5, 4, 6, 8 };

    List<Integer> prime = new ArrayList<Integer>(), even = new ArrayList<Integer>();
    List<Integer> other = new ArrayList<Integer>(), ordered = new ArrayList<Integer>();

    // Start adding until 1st prime appear
    boolean firstPrime = false;

    for (Integer number : integers) {
        if (isPrime(number)) {
            prime.add(number);
            firstPrime = true;
        } else if (firstPrime && isEven(number)) {
            even.add(number);
        }

        // To have control of the order of appearance
        if (firstPrime) other.add(number);

        // If I have at least 1 prime and 2 even, then add them
        // to my ordered list and remove them from all my other lists
        if(prime.size() >= 1 && even.size() >= 2){
            ordered.add(prime.get(0));
            ordered.add(even.get(0));
            ordered.add(even.get(1));

            other.remove(prime.get(0));
            other.remove(even.get(0));
            other.remove(even.get(1));

            even.remove(1);
            even.remove(0);
            prime.remove(0);
        }
    }

    ordered.addAll(other);

    System.out.println(ordered);
}

If you run this example, you will have

[5, 8, 4, 7, 6, 8, 9, 5]
Alex S. Diaz
  • 2,637
  • 2
  • 23
  • 35