1

私は数時間働いて、ビルドされ実装されたアレイに基づいてスタックを取得しようとしています。いくつかのソースを確認しましたが、ArrayStackクラスが正しく構築されているようです。ただし、デバッグを実行すると、「head」はnullのままになり、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メソッドはサイズ変数に対してspをチェックする必要があります。現在、isEmptyチェックとして動作しています:-)

于 2013-03-14T00:37:22.490 に答える
1

私は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();
    }
}
于 2013-03-14T00:45:24.847 に答える
1

自己定義のコンストラクターを使用していません。デフォルトのものを使用しているため、sp変数は「-1」ではなく「0」になります。これにより、プッシュ後の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 に答える
0

「Hello」(最初のオブジェクト)を押すと、 sp0になり、head[0]が割り当てられます。この瞬間から、IsFullはまだテスト中であるため(sp == -1)、それ以降のすべての「プッシュ」は何も生成しません。

于 2013-03-14T00:41:11.910 に答える