2

整数配列 (5 つの要素) 内の要素のすべての組み合わせを計算し、これらの組み合わせを ArrayList に出力するプログラムを Java で作成しようとしています。以下に私のコードを含めました。

ビット演算を使用して組み合わせを見つけます。各組み合わせは、「writeitem」と呼ばれる ArrayList(Integer) として構築されます。次に、これらを「マスター」と呼ばれる別の ArrayList に格納します。これは、ArrayList(ArrayList(Integer)) の形式にする必要があります。[フォーマット上の理由から、<> は () に置き換える必要があります。それ以外の場合は表示されません...]

各組み合わせを「マスター」ArrayList に保存しようとすると、問題が発生します。以下のコードを実行すると、printf 関数は組み合わせが正しく構築されていることを示します。ただ、一度「master」に「追加」してほしいと頼むと、「master」の末尾に追加されないようです。むしろ、「マスター」のすべてが、構築されたばかりの組み合わせの i 個のコピーで上書きされます。

したがって、たとえば、[1,2,3,4,5] で関数を呼び出すと、「マスター」配列は [1,2,3,4,5] の 31 個のコピーになります (31 番目の組み合わせ見つけられた)。

これは、ネストされた配列リストを使用することと関係があると思いますが、私が望むものを達成するためのより良い方法があります。しかし、他の初心者のエラーを犯している可能性もあります。

static ArrayList<ArrayList<Integer>> master = new ArrayList<ArrayList<Integer>>();
public static void generatecombs(int[] x){

    ArrayList<Integer> writeitem = new ArrayList<Integer>(); //empty list to construct each comb

    for(int i=1;i<32;i++){

        writeitem.clear(); //clear before constructing next combination

        if((i & 1)>0){          //check if each element is present in combination
            writeitem.add(x[0]);
        }
        if((i & 2)>0){
            writeitem.add(x[1]);
        }
        if((i & 4)>0){
            writeitem.add(x[2]);
        }
        if((i & 8)>0){
            writeitem.add(x[3]);
        }
        if((i & 16)>0){
            writeitem.add(x[4]);
        }

        System.out.printf("The %dth combination is %s\n", i,writeitem);
        master.add(writeitem); //output constructed element
        System.out.printf("The collection so far is: %s\n", master);
    }
}
4

5 に答える 5

1

新しいものをループ内に移動します

static ArrayList<ArrayList<Integer>> master = new ArrayList<ArrayList<Integer>>();

public static void generatecombs(int[] x){

    for(int i=1;i<32;i++){

        ArrayList<Integer> writeitem = new ArrayList<Integer>(); // new list to construct each comb
        if((i & 1)>0){          //check if each element is present in combination
            writeitem.add(x[0]);
        }
        if((i & 2)>0){
            writeitem.add(x[1]);
        }
        if((i & 4)>0){
            writeitem.add(x[2]);
        }
        if((i & 8)>0){
            writeitem.add(x[3]);
        }
        if((i & 16)>0){
            writeitem.add(x[4]);
        }

        System.out.printf("The %dth combination is %s\n", i,writeitem);
        master.add(writeitem); //output constructed element
        System.out.printf("The collection so far is: %s\n", master);
    }
}
于 2013-10-02T22:28:19.030 に答える
0

その clear() method.from for loop.after を削除します。すべての反復後に clear() が arraylist から値を削除すると、for 内に arraylist が作成されます。

于 2013-10-02T22:26:26.507 に答える
0

の構造をwriteitemfor ループ内に移動します。同じ配列を再利用したくありません。

于 2013-10-02T22:28:41.767 に答える
0

もう 1 つの解決策は、writeItem をクリアする前に、親リストに追加するときにクローンを作成することです。

master.add(writeitem.clone()); 
于 2013-10-02T22:30:29.033 に答える
0

31 個のコピーを取得している理由は、for ループを実行しているためです。writeitem毎回配列をきれいに拭き取り、配列に追加し、for ループ内にある間にそれを出力し、さらに 30 回繰り返します。 32ヒット。

削除writeitem.clear();して、それをどのように処理するかを確認してください

于 2013-10-02T22:31:45.460 に答える