Изключение за масив извън границите, Йосиф Флавий

Изглежда не мога да разбера защо продължавам да получавам тази грешка! За първи път се занимавам с опашки. Сигурен съм, че решението е просто и вероятно пропускам нещо основно. Всякакви насоки/помощ се оценяват високо:

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-ти човек, докато остане само един човек. Легендата разказва, че Йосиф измислил къде да седне, за да избегне елиминирането. Напишете клиент на Queue Josephus, който взема N и M от командния ред и отпечатва реда, в който хората са елиминирани (и по този начин ще покаже на Josephus къде да седне в кръга).


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 (например), трябва да отидете на Run as, Run configurations и да добавите някои аргументи в полето Program arguments. Можете също да замените първия си ред с ръчно въведени стойности:

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
Имате МасивOutOfBoundException. Опашката не е масив, мисля, че проблемът идва от начина ви да извикате програмата, тъй като единственият масив, който използвате, е args. Кой ред повдига изключението? - person Dici; 05.09.2014
comment
@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 Ето защо винаги трябва да маркирате реда, където възниква грешката. Тази информация се променя много. - 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