Почему я получаю NumberFormatException при преобразовании String Array в int Array? - PullRequest
1 голос
/ 11 марта 2019

Я не получаю сообщение об ошибке при запуске кода на IntelliJ .Однако, когда я пытаюсь передать свой Кодекс для задания, над которым я работаю, я получаю NFE для обоих тестовых случаев.Я удалил весь свой код и позволил только тестам, приведенным ниже, проходить тест.Где-то здесь должно быть NumberFormatException.

public class Search {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        sc.nextLine();
        int[] list = new int[n];
        String [] tokens = sc.nextLine().trim().split(" ");

        for (int i=0; i<tokens.length;i++){
            list[i]=Integer.parseInt(tokens[i]);
        }
    }
}

Я прочитал о двойных пробелах и проверил это с помощью: System.out.println(Arrays.asList(tokens).contains("")); Вывод был ложным, так что это не вариант.Как видите, я уже использую trim().Буду признателен за вашу помощь.Луи

Эддит: Хорошо, здесь что-то подозрительное.Я добавил

System.out.println(Arrays.asList(tokens).contains(""));
    System.out.println(Arrays.toString(tokens));

к своему коду и передал его в контрольные примеры.В то время как IntelliJ выдаст false, а затем массив целых чисел, тестовый пример выдает: true [].Поэтому вы все правы, и я просто ошибочно предположил, что входные данные в моих тестовых примерах были бы аналогичны входным данным, приведенным мной в задании

Edit2:

УЖЕ!Я понял.Входные данные тестовых случаев были просто не того же формата, что и входные данные моего теста, которые выглядели примерно так:

10
8 8 9 12 110 111 117 186 298 321
2
8 13

Я предполагаю, что sc.nextLine (), который я включил, пропустил целые числа, которые мне нужны для составления моего списка.Таким образом, настоящая проблема была не в том, что лишние пробелы или что-то еще, просто в том, что я продвинулся дальше, чем я хотел, используя sc.nextLine ().Ответ, который дал мне подсказку, в которой я нуждался, даже если я не думаю, что это было предназначено, пришел от Андроника.В любом случае, спасибо всем.

Ответы [ 4 ]

2 голосов
/ 11 марта 2019

Существует несколько возможных причин:

  1. В tokens есть ненулевое число, например.9 1! 3 x 3 ...
  2. Токены разделены более чем на один пробел - например, 9 3

Вы должны быть в состоянии определить это по тексту исключения числового формата,Например, в случае нескольких пробелов вы получите:

Исключение в потоке "main" java.lang.NumberFormatException: Для входной строки: ""

И для не чисел (например, "a") вы получите:

Исключение в потоке "main" java.lang.NumberFormatException: Для входной строки: "a"

Есть, конечно, множество возможных решений, в зависимости от того, что вы хотите сделать, когда сталкиваетесь с недопустимым вводом (игнорируете ли вы это? Выбрасываете специальное исключение? Пытаетесь удалить не числа?)

Когда вы знаете, что ваши входы разделены пробелами, но не знаете, сколько пробелов, вы можете использовать регулярное выражение для нацеливания на несколько пробелов в вашей команде split:

str.split("\\s+"); // splits on one or more whitespace including tabs, newlines, etc.

Затем для обработки нецифровых чисел в вашем списке токенов вы можете добавить проверку в свой цикл for:

for(int i = 0; i < tokens.length; i++) {
  if(tokens[i].matches("\\d+")) {
    list[i] = Integer.parseInt(tokens[i]);
  } else {
    // Handle error case for non-digit input
  }
}
2 голосов
/ 11 марта 2019

Если вы знаете, что в качестве входных данных будет целое число, и вы не беспокоитесь о разборе, почему бы не использовать его вместо этого?

int input = sc.nextInt();

В вашем решении вам придется сделать:

Arrays.stream(sc.nextLine().trim().split(" ")).filter(s -> !s.matches("\\s")).toArray(String[]::new);
\\ or simplier
sc.nextLine().trim().split("\\s+")
1 голос
/ 11 марта 2019

Вероятно, это связано с большим количеством пробелов между числами.

Например,

9    8 7 9    1
  ^^       ^^
*Note: You have more than one spaces here.

Так будет выглядеть ваш массив после разбиения,

tokens = {"9", "", "", "", "8", "7", "9", "", "", "", "1"}

Выше будет выброшено NumberFormatException из-за лишних пробелов.

Вы можете попробовать trimming содержимое снова,

int i = 0;
for (String token : tokens){
    token = token.trim();
    if (!"".equals(token)) {
        list[i++] = Integer.parseInt(token);
    }
}
0 голосов
/ 11 марта 2019

Пожалуйста, измените ваш код следующим образом:

public class Example {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter the size of the array : ");
        int n = sc.nextInt();
        sc.nextLine();
        int[] list = new int[n];
        System.out.println("Enter a string : ");
        /** This regex will work for string having more than one space. */ 
        String trimmedToken = sc.nextLine().replaceAll("\\s+", " ");
        String[] tokens = trimmedToken.split(" ");
        for (int i = 0; i < tokens.length; i++) {
            list[i] = Integer.parseInt(tokens[i]);
            System.out.println(list[i]);
        }
        sc.close();
    }

}

Консольный ввод:

Enter the size of the array : 
5
Enter a string : 
1       2     3      4    5

Вывод:

1
2
3
4
5
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...