【问题标题】:Array out of bounds exception, Josephus数组越界异常,约瑟夫斯
【发布时间】:2014-09-04 22:36:14
【问题描述】:

我似乎无法弄清楚为什么我不断收到此错误!这是我第一次处理队列。我确信解决方案很简单,我可能缺少一些基本的东西。非常感谢任何指导/帮助:

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 个人,直到只剩下一个人。传说约瑟夫斯为了避免被淘汰而想出了坐在哪里。编写一个队列客户端 Josephus,从命令行获取 N 和 M,并打印出人员被淘汰的顺序(从而显示 Josephus 在圆圈中的位置)。

【问题讨论】:

  • for (int i = 0; i &lt; n; i++) q.remove(new Integer(i)); ...您从新队列中删除了某些内容?那应该如何工作?您应该改用q.add(...)q.remove(x); 行应该做什么? remove 方法不接受任何参数。
  • 调用时是否将参数传递给 main 方法?唯一能够抛出此异常的语句是使用 args 数组的 n 和 m 声明。

标签: java arrays queue bounds josephus


【解决方案1】:

你调用你的程序的方式不对...如果你使用命令行,你必须提供参数:

java Josephus 5 6

否则,如果您使用 Eclipse(例如),则必须转到运行方式、运行配置,并在程序参数字段中添加一些参数。您还可以通过手动输入值来替换第一行:

int n = 10, m = 5;

我用随机的 (m,n) 值集运行它,它运行时没有任何错误(但是,它没有打印任何东西)。

【讨论】:

    【解决方案2】:

    你有:

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

    为什么要从新创建的(空)队列中删除项目?请尝试添加它们!

    q.add(new Integer(i));
    

    【讨论】:

    • 我尝试添加它们,而不是从队列中删除它们。一切都编译了,但是当我运行时,我仍然得到越界异常
    • 您有一个 ArrayOutOfBoundException。队列不是数组,我认为问题出在您调用程序的方式上,因为您使用的唯一数组是 args。哪一行引发了异常?
    • @Smn21 你应该重新考虑q.remove(x);这一行。您已经从队列中删除了元素 x。如果你想删除相似的元素,那么这也行不通,因为remove(Object o) 只删除了一个元素。如果您必须在列表中列出它们,那么其中一个将保留在队列中。
    • @Dici 'int n = Integer.parseInt(args[0]),'
    • 所以我是对的,你没有将任何参数传递给你的程序。它永远不会像这样工作:) 请看看我的答案。
    【解决方案3】:

    Java 认为您正在尝试在 while 循环下 if 语句的 else 语句中调用 remove(int index),因为您传入的是 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]);
    

    【讨论】:

    • remove(int index)?没有这样的方法……至少我找不到。 Queue支持remove(),实现的接口Collection支持remove(Object o)
    • 仍然出现同样的越界错误,我已经复制了我在 for 循环中所做的事情
    • 类 java.util.linkedlist 支持remove(int index)Oracle docs
    • LinkedList 可能支持,但q 的类型是Queue 而这种类型不支持。所以他无法访问该方法。他应该将 q 声明为 (Linked)List 来做到这一点。
    【解决方案4】:

    当您尝试访问不存在的数组元素时,将发生数组越界异常。

    检查

    args.length >= 2 在尝试访问此数组的前 2 个元素之前。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-20
      相关资源
      最近更新 更多