1

我需要从数组中填充一个堆栈,然后按顺序打印出元素,然后再次颠倒顺序。我遇到的问题是我得到一个 ArrayIndexOutOfBoundsException 并且无法弄清楚它来自哪里。我已经尝试通过调试运行,它出现在我弹出元素时它永远不会到达最后一个元素。下面是我的代码:

public class arrayStack {

    private int top;
    private String[] storage;

    public arrayStack(int capacity)
    {
        storage = new String[capacity];
        top = -1;
    }

    public boolean isEmpty() {
        return (top == 0);
    }

    String peek() {
        return storage[top];    
    }

    String pop() {
        top--;
        return storage[top];
    }

    public void push(String str) {
        top++;
        storage[top] = str;
    }

}

StackMain.java:

public class StackMain {

    public static void main(String[] args) {
        //int j = 5;
        String[] list = new String[5];

        list[0] = "Beware";
        list[1] = "The";
        list[2] = "Ides";
        list[3] = "Of";
        list[4] = "March";

        arrayStack stack = new arrayStack(5);

        for(int i = 0; i < list.length; i++)
        {
            stack.push(list[i]);
        }

        for(int j = 0; j < list.length; j++)
            System.out.println(stack.pop());

    }

}
4

8 回答 8

3

pop()中,您需要返回被弹出的项目,即在 的旧值的索引处的项目top。最干净的方法是将功能更改为

String pop() {
    return storage[top--];
}

编辑
您还需要更改isEmpty()return (top == -1). 您还可以更改实现以使用size(元素的数量)而不是top(最高元素的索引),就像其他人提到的那样。

于 2012-02-29T02:20:02.943 回答
1

在你的构造函数中arrayStack,你应该设置top为 0,而不是 -1。在您的isEmpty方法中,您甚至检查了top == 0, 所以显然top == 0意味着空,而不是top == -1。这就是为什么在从堆栈中弹出值时总是会错过最后一个元素的原因;将第一个元素增量top为 0。

哦,我错过了汤姆在下面所说的内容:top在找到顶部的值之前递减将返回错误的元素。下面的代码更可取,但这对于初学者来说可能更容易理解:

public String pop() {
    String topValue = storage[top];
    top--;
    return topValue;
}
于 2012-02-29T02:20:22.603 回答
1

如果你push(String)只有一个元素,top 初始化为 -1,那么在 push 之后 top 的值是多少?

现在看看你的函数,它在尝试获取请求的元素之前pop()递减 top ,那么如果你只推送一个元素,它将尝试访问什么数组索引?

于 2012-02-29T02:20:26.847 回答
1

由于您从top-1 开始,一旦您从 String 数组中添加了 5 个元素,您top将是 4,这是不正确的,因为您有 5 个元素。

然后,当您尝试弹出堆栈 5 次时,top返回 -1 并且storage[-1]不存在,因此您得到一个ArrayIndexOutOfBoundsException

从 0开始top

或者,如果您top在从堆栈中检索元素后递减,您将不会收到错误;但最好从top0 开始,因为top它实际上代表了堆栈中元素的数量。

于 2012-02-29T02:20:27.577 回答
1

请将问题标记为作业。问题出在 pop() 函数中。您首先减少 top 的值,然后返回元素。但是当您检查 push() 函数时,您是先递增然后添加元素。因此,如果您在top--从堆栈中获取元素后将其移至,您的问题将得到解决。

于 2012-02-29T02:21:58.200 回答
1

您的弹出方法不正确。在您的代码中,top 从负 1 开始。

当你 push 一个元素时,top 变为 0。当你 pop 一个元素时,top 在你访问元素之前变为 -1。

另外,您的空方法不正确。在堆栈的初始状态,top = -1,isEmpty 检查它是否返回 0。最初堆栈应该是空的。

于 2012-02-29T02:23:02.360 回答
1

您的 pop() 函数必须更改。您必须将 storage[pop] 存储在临时变量中,然后将 top 减 1,然后返回临时变量

于 2012-02-29T02:23:03.660 回答
1

如果您可以包含 java 1.5 泛型工具来实现堆栈,那就太好了。然后您的堆栈将更加灵活。它可以容纳任何类型的对象(在您的情况下只有字符串)并且还有一个建议是您应该告诉的 pop 方法垃圾收集器丢弃到弹出对象如下。(如果您使用泛型)以下是有效的 Java 版本 2 中提到的更灵活的堆栈实现。

// Initial attempt to generify Stack = won’t compile!
public class Stack<E> {
private E[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack() {
elements = (E[])new E[DEFAULT_INITIAL_CAPACITY];
}
public void push(E e) {
ensureCapacity();
elements[size++] = e;
}
public E pop() {
if (size==0)
throw new EmptyStackException();
E result = elements[--size];
elements[size] = null; // Eliminate obsolete reference
return result;
}
于 2012-02-29T03:00:32.017 回答