【问题标题】:Trying to implement Array Stack in Java but Push is not working尝试在 Java 中实现数组堆栈但推送不起作用
【发布时间】:2013-03-02 04:51:29
【问题描述】:

我已经工作了几个小时,试图获得一个基于构建和实现的数组的堆栈。我检查了几个来源,看起来我的 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)

【问题讨论】:

    标签: java arrays stack


    【解决方案1】:

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

    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 检查:-)

    【讨论】:

    • 我认为这就是 'public void stack(T t) 方法在做什么?
    • @ChristopherDay - 确实如此,但您没有在上面的主要方法中调用该方法!另外,请参阅我对诱杀对象的评论!您应该始终确保(如果可能的话)您的对象处于正常状态并准备好在构建后使用。
    • 请参阅下面的 PM 77-1 答案,了解与您的 isFull 相关的其他附加错误,其语义类似于 isEmpty 调用
    • 也阅读了附加评论,我现在明白你的意思了,哈哈。感谢您的时间和帮助!有时我希望我们能投票支持助攻。
    【解决方案2】:

    我注意到两件事。

    首先,正如其他人提到的,您需要创建一个构造函数并初始化数组。其次,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();
        }
    }
    

    【讨论】:

    • 感谢您的时间和解释!我只是盯着谷歌 isFull() 来找出我缺少的东西。非常感谢!
    • @ChristopherDay 很高兴我能帮上忙。
    【解决方案3】:

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

    将您的 stack 方法更改为

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

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

    【讨论】:

    • 非常感谢;我必须对您的建议进行额外的更改。
    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-07
      • 1970-01-01
      • 2020-10-24
      • 2021-06-24
      • 2018-03-11
      • 2016-11-25
      • 2014-04-20
      • 2010-12-15
      相关资源
      最近更新 更多