Не сохраняет слова в массиве - PullRequest
0 голосов
/ 17 апреля 2020

У меня, возможно, простой вопрос. Я пытаюсь прочитать файл, и я хочу добавить каждое слово в мой массив «фразу». Проблема возникает в течение l oop. Я получил исключение "индекс 0 вне границ для длины 0". Можете ли вы помочь мне с этим?

    String [] tokens;
    String line;
    String hash = " ";
    int n = 0;
    String [] phrase = new String [n];

    public void loadFile()
    {
        try
        {
            @SuppressWarnings("resource")
            BufferedReader br = new BufferedReader(new FileReader("z3data1.txt"));

            while((line = br.readLine()) != null)
            {
                tokens = line.split("[ ]");
                n += tokens.length;
            }
            for(int j = 0; j<tokens.length; j++)
            {
                phrase[j] = tokens[j];
            }
        }
        catch(IOException ex)
        {
            ex.printStackTrace();
        }
   }

Ответы [ 3 ]

0 голосов
/ 17 апреля 2020

Пара наблюдений.

  • вы получаете ошибку, потому что ваш массив недостаточно велик
    и индекс j превышает его размер.
  • вы сохраняете перезапись токенов в while loop. В то время как l oop необходимо включить копирование токенов в массив фраз.

Поэтому попробуйте следующее:

      while((line = br.readLine()) != null) {
              tokens = line.split("[ ]");
              n += tokens.length; // don't really need this.
          //starting offset to write into phrase
          int len = phrase.length;
          phrase = Arrays.copyOf(phrase,phrase.length + tokens.length);

          for(int j = 0; j<tokens.length; j++) {
              phrase[j + len] = tokens[j];
          }
       }

Это утверждение

phrase = Arrays.copyOf(phrase,phrase.length + tokens.length)

Копирует содержимое фразы и увеличивает размер массива для обработки записи токенов.

Другая (и, вероятно, предпочтительная) альтернатива - использовать List<String>, который увеличивается по мере необходимости.

List<String> phrase = new ArrayList<>();

for(int j = 0; j<tokens.length; j++) {
       phrase.add(tokens[j]);
}
// or skip the loop and just do
Collections.addAll(phrase,tokens);

Одно наблюдение. Я не знаю, на что вы делитесь, но ваше заявление о расколе выглядит подозрительно.

0 голосов
/ 17 апреля 2020

Проблема, с которой вы столкнулись, связана со следующим объявлением:

int n = 0;
String [] phrase = new String [n];

Это объявление эквивалентно String [] phrase = new String [0]. Поскольку phrase [] имеет размер 0, вы получите ArrayIndexOutOfBoundsException при попытке добавить к нему любую строку. Вы можете понять это далее с помощью следующего примера:

class Main {
    public static void main(String[] args) {
        String[] array = new String[0];
        array[0] = "Hello World!";
    }
}

Вывод:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
    at Main.main(Main.java:4)

Поскольку вы не знаете общее число токенов в файле, вы должны использовать List вместо массива. List работает как динамический c массив (т. Е. Массив, размер которого не фиксирован).

List<String> phrase = new ArrayList<String>();

public void loadFile() {
    try {
        @SuppressWarnings("resource")
        BufferedReader br = new BufferedReader(new FileReader("z3data1.txt"));

        while ((line = br.readLine()) != null) {
            tokens = line.split("[ ]");
            for (String token : tokens) {
                phrase.add(token);
            }
        }
        System.out.println(phrase);
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}
0 голосов
/ 17 апреля 2020

Вы устанавливаете n в 0, поэтому фраза также имеет длину 0, когда вы говорите String[] phrase = String[n]. Поэтому вы ничего не можете добавить к нему.

Если вы хотите что-то переменной длины, вы можете использовать ArrayList. В приведенном ниже коде вы можете напрямую использовать Collections.addAll, чтобы разделить строку и поместить все в фразу ArrayList.

    String line;
    //Note that you can get rid of tokens here, since it's being inlined below
    ArrayList<String> phrase = new ArrayList<>();

    public void loadFile()
    {
        try
        {
            @SuppressWarnings("resource")
            BufferedReader br = new BufferedReader(new FileReader("z3data1.txt"));

            while((line = br.readLine()) != null)
            {
                //No need for a for-loop below, you can do everything in one line
                Collections.addAll(phrase, line.split("[ ]"));
            }
        }
        catch(IOException ex)
        {
            ex.printStackTrace();
        }
   }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...