Я получаю сообщение об ошибке «Индекс 5 выходит за пределы длины 5», но не знаю, что изменить - PullRequest
0 голосов
/ 14 февраля 2020

Я довольно новичок в кодировании, поэтому, пожалуйста, потерпите меня, я просто экспериментирую с способами перемешать массив для возможного использования при перетасовке колоды карт в карточной игре, которую я создаю в Java. Я знаю, что индекс 5 выходит за пределы длины 5, но меня озадачивает то, что ошибка ВСЕГДА не появляется. Иногда я пытаюсь запустить свой код, и он работает просто отлично, в других случаях я получаю сообщение об ошибке, даже если я ничего не менял между его запусками.

public class Card{

    public static void shuffle(Object[] array) {

        int noOfCards = array.length;

        for (int i = 0; i < noOfCards; i++) {

            int s = i + (int)(Math.random() * (noOfCards - 1));

            Object temp = array[s]; //this is the first line it says has a problem
            array[s] = array[i];
            array[i] = temp;
        }
    }

    public static void main(String[] args) {

        String[] strOfCards = {"A","B","C","D","E"};

        Card.shuffle(strOfCards); //this is the second line that has a problem
        for(int i = 0; i < strOfCards.length; i++) {
            System.out.println(strOfCards[i] + " ");
        }
    }
}

Я не знаю, как это изменить ошибочные линии, любые предложения приветствуются! *** Я попытался изменить количество букв в строке, но затем ошибка меняется вместе с ним, например, «Индекс 6 за пределами длины 6»

Ответы [ 5 ]

3 голосов
/ 14 февраля 2020

Рассмотрим строки:

for (int i = 0; i < noOfCards; i++) {
    int s = i + (int)(Math.random() * (noOfCards - 1));
    Object temp = array[s]; //this is the first line it says has a problem

i варьируется от 0 до noOfCards - 1 Ваше выражение случайного числа варьируется от 0 до noOfCards - 2 Таким образом, s варьируется от 0 до (2 * noOfCards) - 3

Тогда array[s] будет генерировать исключение всякий раз, когда s> = noOfCards

Это не происходит каждый раз, когда вы запускаете его, потому что иногда все случайные числа оказываются под noOfCards

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

Random random = new Random();
int s = (i + random.nextInt(noOfCards - 1)) % noOfCards;

Я понимаю, что вы используете это как возможность обучения, но в случае, если вы не знали, есть Collections.shuffle метод, который можно использовать для перемешивания коллекций, таких как ArrayList в одной команде.

0 голосов
/ 14 февраля 2020

Вы должны помнить, что индексы начинаются с нуля в Java.

Обратите внимание на пару вещей:
- сделать вещи окончательными, если они окончательны
- использовать SecureRandom : оно более случайное, чем Random
- используйте метод SecureRandom nextInt(n), чтобы получить int в вашем диапазоне
- обратите внимание на использование Streams для распечатки результата

import java.security.SecureRandom;
import java.util.stream.Stream;

public class Card {

    public static void shuffle(final Object[] array) {

        final SecureRandom random    = new SecureRandom();

        final int          noOfCards = array.length;

        for (int i = 0; i < noOfCards; i++) {

            final int    s    = random.nextInt(noOfCards);

            final Object temp = array[s];

            array[s] = array[i];
            array[i] = temp;
        }
    }

    public static void main(final String[] args) throws Exception {

        final String[] strOfCards = {"A","B","C","D","E"};

        Card.shuffle(strOfCards);

        Stream.of(strOfCards).forEach(System.out::println);
    }
}

Если вы хотите использовать List, он будет немного компактнее:

import java.security.SecureRandom;
import java.util.*;
import java.util.stream.IntStream;

public class Card {

    public static void main(final String[] args) throws Exception {

        final SecureRandom random = new SecureRandom();

        final List<String> cards  = Arrays.asList("A", "B", "C", "D", "E");

        IntStream.range(0, cards.size()).forEach(i ->
            Collections.swap(cards, i, random.nextInt(cards.size()))
        );
        cards.forEach(System.out::println);
    }
}
0 голосов
/ 14 февраля 2020

изменить эту строку

int s = i + (int)(Math.random() * (noOfCards - 1));

на эту

int s =  (int)(Math.random() * (noOfCards - 1));

просто удалить переменную i из приведенного выше кода

0 голосов
/ 14 февраля 2020

Максимальный индекс массива с длиной N равен (N-1). Код должен быть таким:

public static void shuffle(Object[] array) {
    int noOfCards = array.length;
    Random random = new Random();
    for (int i = 0; i < noOfCards; i++) {
        int s = random.nextInt(noOfCards);

        Object temp = array[s];
        array[s] = array[i];
        array[i] = temp;
    }
}
0 голосов
/ 14 февраля 2020

Вот строка, которая вызывает проблему:

int s = i + (int)(Math.random() * (noOfCards - 1));

Всякий раз, когда значение s>> 5, массив [s] будет указывать на что-то вне границ.

Для Например, я могу быть 3, если Math.random () возвращает что-то вроде 0,5, то 3 + (int) (0,5 * 4) равно 5 , что выходит за пределы (0..4)

Это происходит не всегда, потому что иногда Math.random () генерирует достаточно малое число, поэтому оценка s меньше 5.

Чтобы убедиться, что значение s всегда находится в диапазоне (0..4), вы должны модулировать результат до 5.

Вот как должна выглядеть строка:

int s = (i + (int)(Math.random() * (noOfCards - 1))) % 5;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...