2013-03-14 88 views
1

我一直在工作了幾個小時,現在試圖獲得基於數組構建和實現的堆棧。我檢查了幾個來源,看起來像我的ArrayStack類正確構造。但是,當我運行調試時,'head'保持爲空,並且大小爲& sp回到0:因此,沒有任何內容實際上被推入堆棧。有人能幫助我瞭解我實施的不正確嗎?試圖在Java中實現數組堆棧,但推不工作

這裏是我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) 

我在公共無效變量推(T t)

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

回答

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(); 
    } 
} 
+0

謝謝你的時間和解釋!我只是盯着Google的isFull()來找出我錯過的東西。不勝感激! – Chris 2013-03-14 00:54:47

+0

@ChristopherDay很高興我能幫到你。 – 2013-03-14 00:57:32

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方法應該是檢查對大小可變的SP,現在它被表現爲一個檢查的isEmpty :-)

+0

我認爲這就是'公共無效堆棧(T t)方法在做什麼? – Chris 2013-03-14 00:39:27

+1

@ChristopherDay - 確實如此,但是您並未在上面的主要方法中調用該方法!另外,請參閱我的關於誘惑被困對象的評論!您應該始終確保(如果可能的話)您的物體處於正常狀態,並且在施工後可以使用。 – 2013-03-14 00:41:30

+0

請參閱下面的PM 77-1答案,其餘的bug與您的isFull在語義上與isEmpty調用相關 – 2013-03-14 00:44:53

1

您沒有使用任何selfdefined構造。您正在使用默認值,這會導致您的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]; 
} 

,使之成爲selfdefined構造。

+0

非常感謝你;我不得不作出額外的改變你的建議工作。 – Chris 2013-03-14 00:44:55

0

按下「Hello」(第1個對象)後sp變爲並指定head [0]。從這一刻起,所有進一步的「推送」將不會產生任何結果,因爲您的IsFull仍在測試(sp == -1)。