Массив за пределами исключения, Иосиф Флавий

Я не могу понять, почему я продолжаю получать эту ошибку! Я впервые имею дело с очередями. Я уверен, что решение простое, и я, вероятно, упускаю что-то основное. Любое руководство/помощь приветствуется:

import java.util.LinkedList;
import java.util.Queue;


public class Josephus{
  public static void main(String[] args)
    {
        int n = Integer.parseInt(args[0]),
            m = Integer.parseInt(args[1]);

        Queue<Integer> q = new LinkedList<Integer>();
    for (int i = 0; i < n; i++)
        q.remove(new Integer(i));

    int k = 0;
    while (!q.isEmpty())
    {
        int x = q.remove();

        if (++k % m == 0)
            System.out.print(x + " ");
        else
            q.remove(x);

    System.out.println(x + " ");
    }
    }
}

Первоначальная подсказка для этого кода выглядит следующим образом: Задача Иосифа Флавия. В задаче Иосифа Флавия из древности N человек находятся в отчаянном положении и соглашаются на следующую стратегию сокращения населения. Они выстраиваются в круг (на позициях, пронумерованных от 0 до N–1) и продолжают двигаться по кругу, уничтожая каждого M-го человека, пока не останется только один человек. Легенда гласит, что Иосиф Флавий придумал, где сесть, чтобы не быть уничтоженным. Напишите клиент очереди Иосифа, который берет N и M из командной строки и выводит порядок, в котором люди удаляются (и таким образом показывает Иосифу, где сидеть в круге).


person Smn21    schedule 04.09.2014    source источник
comment
for (int i = 0; i < n; i++) q.remove(new Integer(i)); ... вы что-то удаляете из новой очереди? Как это должно работать? Вместо этого вы должны попробовать q.add(...). А что должна делать строка q.remove(x);? Метод remove не принимает никаких аргументов.   -  person Tom    schedule 05.09.2014
comment
Вы передаете параметры своему основному методу при его вызове? Единственными операторами, способными генерировать это исключение, являются объявления n и m с использованием массива args.   -  person Dici    schedule 05.09.2014


Ответы (4)


Вы неправильно вызываете свою программу... если вы используете командную строку, вы должны указать параметры:

java Josephus 5 6

В противном случае, если вы используете Eclipse (например), вы должны перейти в «Запуск от имени», «Запустить конфигурации» и добавить некоторые аргументы в поле «Аргументы программы». Вы также можете заменить свою первую строку значениями, введенными вручную:

int n = 10, m = 5;

Я запускал его со случайными наборами значений (m,n), и он работал без ошибок (однако он ничего не печатал).

person Dici    schedule 04.09.2014

У тебя есть:

Queue<Integer> q = new LinkedList<Integer>();
for (int i = 0; i < n; i++)
    q.remove(new Integer(i));

Почему вы удаляете элементы из вновь созданной (пустой) очереди? Попробуйте добавить их вместо этого!

q.add(new Integer(i));
person DavidPostill    schedule 04.09.2014
comment
я попытался добавить их, вместо того, чтобы удалить их из очереди. Все компилируется, но когда я запускаю, я все еще получаю исключение за пределами границ - person Smn21; 05.09.2014
comment
У вас есть исключение ArrayOutOfBoundException. Очередь - это не массив, я думаю, проблема связана с вашим способом вызова программы, поскольку единственный массив, который вы используете, - это args. Какая строка вызывает исключение? - person Dici; 05.09.2014
comment
@ Smn21 Smn21 Вы должны переосмыслить строку q.remove(x);. Вы уже удалили элемент x из очереди. Если вы хотите удалить похожие элементы, это тоже не сработает, потому что remove(Object o) удаляет только один элемент. Если у вас есть один из них в вашем списке, то один из них останется в очереди. - person Tom; 05.09.2014
comment
@Dici 'int n = Integer.parseInt(args[0]),' - person Smn21; 05.09.2014
comment
Так что я был прав, вы не передаете никаких параметров в свою программу. Это никогда не сработает так :) Пожалуйста, взгляните на мой ответ. - person Dici; 05.09.2014
comment
@ Smn21 Smn21 Вот почему вы всегда должны отмечать строку, в которой возникает ошибка. Эта информация многое меняет. - person Tom; 05.09.2014

Java думает, что вы пытаетесь вызвать remove(int index) в операторе else оператора if в цикле while, потому что вы передаете int. В качестве обходного пути сделайте то, что вы сделали именно в цикле for.

q.remove(new Integer(x));

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

if (args.length != 2){
    System.out.println("Invalid arguments.");
    return;
}

int n = Integer.parseInt(args[0]),
    m = Integer.parseInt(args[1]);
person DrOverbuild    schedule 04.09.2014
comment
remove(int index)? Нет такого метода... по крайней мере я не могу найти. Queue поддерживает remove(), а реализованный интерфейс Collection поддерживает remove(Object o). - person Tom; 05.09.2014
comment
все еще получаю ту же ошибку за пределами границ, я продублировал то, что сделал в цикле for - person Smn21; 05.09.2014
comment
Класс java.util.linkedlist поддерживает remove(int index). документы Oracle - person DrOverbuild; 05.09.2014
comment
LinkedList может поддерживать это, но тип q — это Queue, а этот тип — нет. Поэтому он не может получить доступ к этому методу. Для этого он должен объявить q как (связанный) список. - person Tom; 05.09.2014

Исключение массива вне границ возникает при попытке доступа к несуществующему элементу массива.

Проверять

args.length >= 2 перед попыткой доступа к первым 2 элементам этого массива.

person Kerstin    schedule 04.09.2014