Как можно оптимизировать решение

Прохожу обучение, есть задача: Напишите программу, которая прочитает из System.in последовательность целых чисел, разделенных пробелами, затем удалит из них все числа, стоящие на четных позициях, и затем выведет получившуюся последовательность в обратном порядке в System.out. Все числа влезают в int. Позиции чисел в последовательности нумеруются с нуля. Пример ввода: 1 2 3 4 5 6 7 8 9 10 Пример вывода: 10 8 6 4 2

Решил вот так:

        LinkedList<Integer> ali = new LinkedList<>();
        StringBuffer str = new StringBuffer();
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextInt()) {
            ali.add(scanner.nextInt());
        }
        scanner.close();

        for (int k = 0; k < ali.size();k++) {
            if (ali.get(k)%2 != 0) {
                ali.remove(k);
            }
        }

        for (int i = 0; i < ali.size(); i++){
            str.append(ali.get((ali.size()-1)-i))
                    .append(" ");

        }
        System.out.print(str.substring(0, str.length()-1));

Проверяющая система не принимает "не правильная реализация метода", хотя в IDE всё работает под заявленные условия. Как это можно оптимизировать? В комментариях к заданию предлагают решать через ArrayDeque/Iterator, не понимаю почему так нельзя, как сделал, через LL. Благодарю за помощь!


Ответы (2 шт):

Автор решения: Дмитрий

Полагаю, что все проще. По описанному вами условию пользователь должен ввести 1 строку, содержащую цифры, разделенные пробелами, а вы вводите по одному инту в цикле. Но самое главное - удалять элементы из коллекции, однолвременно итерируясь по ней обычным циклом, НЕЛЬЗЯ!!! И вообще так делать (удалять элементы из существующей коллекции) крайне нежелательно (если очень надо - итератор в помощь). В таких случаях лучше создать новую коллекцию, а, начиная с Java 8, в этом могут очень сильно помочь стримы с фильтрами. Кроме того, нужно помнить, что пользовательский ввод может содержать ошибки. Что будет с вашей программой, если вместо цифры пользователь введет какую-то букву? А еще мне кажется, что 3 цикла - явный перебор для такой задачи. Попробуйте такой подход (метод apply возвращает Optional, посему а что делать с ним в методе main, решать вам, я просто вывожу результат либо сообщение об ошибке):

import java.util.Arrays;
import java.util.Optional;
import java.util.Scanner;
import java.util.stream.IntStream;

public class Main {

    public static void main(String[] args) {
        String userInput = new Scanner(System.in).nextLine();
        String message = apply(userInput.split(" "))
                .map(result -> Arrays.toString(result))
                .orElseGet(() -> "Incorrect user input!");
        System.out.println(message);
    }

    public static Optional<Integer[]> apply(String[] arr) {
        try {
            return Optional.of(IntStream.range(1, arr.length)
                    .filter(i -> (arr.length - i) % 2 != 0)
                    .mapToObj(i -> Integer.valueOf(arr[arr.length - i].trim()))
                    .toArray(Integer[]::new));
        } catch (NumberFormatException e) {
            return Optional.empty();
        }
    }

}
→ Ссылка
Автор решения: Maxim
ArrayDeque<Integer> ali = new ArrayDeque<>();
    Scanner scanner = new Scanner(System.in);
    int i = 0;
    while (scanner.hasNextInt()) {
        if (i%2 == 0) {
            scanner.next();
        } else {
            ali.add(scanner.nextInt());
        }
        i++;
    }
    scanner.close();
    Iterator<Integer> it = ali.descendingIterator();
    while (it.hasNext()) {
        System.out.print(it.next() + " ");
    }

вот так

→ Ссылка