【问题标题】:ArrayIndexOutOfBoundsException when shuffling a LinkedList改组 LinkedList 时出现 ArrayIndexOutOfBoundsException
【发布时间】:2014-11-25 09:13:39
【问题描述】:

好的,所以我有一个任务,它是这样的:

假设您有一个包含 N 的单链表作为输入 items(Java 中 LinkedList 类的实例)。您应该重新排列 LinkedList 均匀随机。您的算法应该使用对数(或 常数)额外内存的数量和在最坏情况下与 NlogN 成正比的运行时间 案例。

对于算法,我打算使用合并排序,当它合并时,它会以随机方式进行。 但是我的程序被卡住了,因为它抛出了一个ArrayIndexOutOfBoundsException,但它不在我的代码中,而是在 LinkedList.java 中

我对 LinkedList 不是很熟悉,所以我不知道该怎么做,我什至不确定我这样做的方式是否正确。

代码:

import java.util.LinkedList;

public class Q02 {

public static void main(String[] args) {

    LinkedList<Integer> list = new LinkedList<>();
    list.add(1);
    list.add(2);
    list.add(3);
    list.add(4);
    list.add(5);
    list.add(6);
    list.add(7);
    list.add(8);
    list.add(9);
    list.add(0);
    System.out.println("Shuffled list: "+shuffle(list));
}

public static LinkedList shuffle(LinkedList list){
    int node = 10; //just a random node
    if(list.size()<=1){
        return list;
    }
    LinkedList<Integer>list1 = new LinkedList<>();
    LinkedList<Integer>list2 = new LinkedList<>();

    while(!list.isEmpty()){
        list1.add((Integer) list.removeFirst());
        if(!list.isEmpty()){
            list2.add((Integer) list.removeFirst());
        }
    }
    shuffle(list1);
    shuffle(list2);

    if(list2.size() < list1.size()){
        int i = (int)(Math.random() * list2.size());
        list2.set(i, node);
    }

    while(!list1.isEmpty()&&!list2.isEmpty()){
        int rand = (int)(Math.round(Math.random()));
        if(rand == 1){
            list.add(list1.removeFirst());
        }
        else if(rand == 0){
            list.add(list2.removeFirst());
        }
    }
    //If any of list1 or list2 are still empty add everything to list
    if(!list1.isEmpty()){
        list.add(list2.clone());
    }
    if(!list2.isEmpty()){
        list.add(list1.clone());
    }
    list.remove(node);
    return list;
}

}

这里是错误:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 10, Size: 2
at java.util.LinkedList.checkElementIndex(LinkedList.java:553)
at java.util.LinkedList.remove(LinkedList.java:523)
at kth.id2010.lab.lab03.Q02.Q02.shuffle(Q02.java:62)
at kth.id2010.lab.lab03.Q02.Q02.shuffle(Q02.java:39)
at kth.id2010.lab.lab03.Q02.Q02.shuffle(Q02.java:39)
at kth.id2010.lab.lab03.Q02.Q02.shuffle(Q02.java:39)
at kth.id2010.lab.lab03.Q02.Q02.main(Q02.java:22)

【问题讨论】:

  • 您能告诉我们您遇到的错误吗?如果可能,复制/粘贴整个堆栈跟踪。
  • @CoryKlein 编辑了我的帖子,它现在包含错误
  • 只是一个无关的评论:我认为创建输入列表的副本不能满足任务要求算法应该消耗对数(或恒定)量的额外内存
  • @Durandal 实际上确实如此,因为我将其复制到 2 个不同的列表中,消耗的额外内存量是 logN,它是对数。

标签: java algorithm linked-list indexoutofboundsexception


【解决方案1】:

如果您收到ArrayIndexOutOfBoundsException,这意味着您正尝试使用无效索引访问LinkedList 中的某个项目。例如,如果您的 LinkedList10 项目,那么 listOfSize10.set(10, node) 将引发 ArrayIndexOutOfBoundsException

您看到的错误很可能源于以下几行:

int i = (int)(Math.random() * list2.size());
list2.set(i, node);

你能保证i总是大于或等于0且小于list2.size()吗?

更新 在查看您的堆栈跟踪后,看起来错误来自以下几行:

int node = 10; //just a random node
list.remove(node);

当列表中只有10 项时,您显然是在尝试删除索引10(或第十一项)处的项。所以你的数组索引超出了范围。

【讨论】:

  • 我以为我可以使用 remove(object) 并将节点作为对象发送,但我现在意识到它将把它作为一个整数。有没有办法删除该特定节点?因为我不知道它在哪里
  • 我没有尝试过,但它可能会起作用:Integer node = 9; list.remove(node);
  • 因为list 的类型是LinkedList&lt;Integer&gt;,而不是LinkedList&lt;int&gt;
  • 我总是忘记 int 和 Integer 不是一回事。谢谢你,但现在我的列表有 6 个插槽,其中只有 3 个有东西。知道为什么吗?
  • 这可能适合单独的问题。
猜你喜欢
  • 1970-01-01
  • 2020-03-09
  • 1970-01-01
  • 1970-01-01
  • 2011-12-03
  • 1970-01-01
  • 1970-01-01
  • 2011-08-05
  • 2014-12-27
相关资源
最近更新 更多