1

我已经工作了几个小时,试图获得一个基于构建和实现的数组的堆栈。我检查了几个来源,看起来我的 ArrayStack 类构造正确。但是,当我运行调试时,'head' 保持为空,并且 size & sp 回到 0:因此,实际上没有任何东西被压入堆栈。有人可以帮助我了解我错误地实施了什么吗?

这是我的 ArrayStack 类:

public class ArrayStack <T>{
    protected int sp; //empty stack
    protected T[] head; //array
    private int size;

    @SuppressWarnings("unchecked")
    public void stack(T t){
        sp = -1;
        size = 24; //sets the default size of the stack
        head = (T[]) new Object [size];
    }
    public boolean isFull(){
        return sp == -1;
    }
    public void push (T t){
        if (!isFull())
            head[++sp] = t;
    }
    public T pop (){
        if (isFull()){
            return null;
        }
        else 
            return head[sp--];  //LINE 30
    }
}

这是我的主要方法:

public class StacksAndQsMain {

    public static void main(String[] args) {
        //Array Implementation
        ArrayStack<String> as  = new ArrayStack<String>();

        String s = "Hello";
        String s1 = "World";
        String s2 = "Again";

        as.push(s);
        as.push(s1);
        as.push(s2);

        System.out.println (as.pop()); //LINE 15
        System.out.println();
        System.out.println (as.pop());
        System.out.println();
        System.out.println (as.pop());
        System.out.println();
    }

}

最后,这是我的堆栈跟踪:

Exception in thread "main" java.lang.NullPointerException
at stackAndQs.ArrayStack.pop(ArrayStack.java:30)
at stackAndQs.StacksAndQsMain.main(StacksAndQsMain.java:15)

我在 public void push (T t) 时的变量

this       ArrayStack<T>  (id=17)   
head       null 
size       0    
sp     0    
t      "Hello" (id=18)
4

4 回答 4

2

您正在使用该类的默认构造函数,它将所有数据成员初始化为其默认值:

public class ArrayStack <T>{
protected int sp; //empty stack  <-- initialized to 0
protected T[] head; //array <-- initialized to null
private int size; // <-- initialized to 0
// ... snip
}

您需要实现默认构造函数以将此对象状态初始化为您想要的默认值(在 stack() 方法中)。当您调用 push 时,isFull 方法将返回 false(作为默认整数值 0 != -1)。

除了实现默认构造函数,您可以在使用它之前调用 stack(),但是没有理由让您的对象在一个陷阱状态下构造!

此外,您的 isFull 方法应该根据 size 变量检查 sp,现在它的行为类似于 isEmpty 检查:-)

于 2013-03-14T00:37:22.490 回答
1

您没有使用任何自定义构造函数。您正在使用默认值,这会导致您的sp变量为“0”而不是“-1”。这会在您推送之后产生一个sp值,但其中没有数据,这会在您尝试弹出它时导致 NPE。3sp[3]

stack将您的方法更改为

public ArrayStack(T t){
       sp = -1;
       size = 24; //sets the default size of the stack
       head = (T[]) new Object [size];
}

使其成为自定义构造函数。

于 2013-03-14T00:39:23.407 回答
1

我注意到两件事。

首先,正如其他人提到的,您需要创建一个构造函数并初始化数组。其次,该isFull方法应该检查 sp != this.size -1,基本上确保您没有达到堆栈实现的 24 个元素的限制。改完后,isFull应该在push方法中否定if条件,检查栈是否未满。另外,我会删除对pop方法的检查以检查是否堆栈isFull,为什么仅仅因为堆栈已满而阻止某人弹出元素?而是检查堆栈是否为空。

public class ArrayStack<T> {
    protected int sp; // empty stack
    protected T[] head; // array
    private int size;

    @SuppressWarnings("unchecked")
    public ArrayStack() {
        sp = -1;
        size = 24; // sets the default size of the stack
        head = (T[]) new Object[size];
    }

    public boolean isFull() {
        return sp == this.size -1;
    }

    public boolean isEmpty() {
        return sp == -1;
    }

    public void push(T t) {
        if (!isFull())
            head[++sp] = t;
    }

    public T pop() {
        if (isEmpty()) {
            return null;
        } else
            return head[sp--]; // LINE 30
    }

    public static void main(String[] args) {
        // Array Implementation
        ArrayStack<String> as = new ArrayStack<String>();

        String s = "Hello";
        String s1 = "World";
        String s2 = "Again";

        as.push(s);
        as.push(s1);
        as.push(s2);

        System.out.println(as.pop()); // LINE 15
        System.out.println();
        System.out.println(as.pop());
        System.out.println();
        System.out.println(as.pop());
        System.out.println();
    }
}
于 2013-03-14T00:45:24.847 回答
0

按下“Hello”(第一个对象)后, sp变为0并分配了 head[0]。从这一刻起,所有进一步的“推动”都不会产生任何结果,因为您的 IsFull 仍在测试 (sp == -1)。

于 2013-03-14T00:41:11.910 回答