2017-09-15 10 views
2

ヒープのアルゴリズムを使用して、リストの各順列を含むリストのリストを作成しています。各順列はそれ自身のリストになります。アルゴリズム内で印刷すると正しく動作しますが、リストリストに追加しようとすると正しく動作せず、すべて同じ配列(4,1,2,3)になります。私はそれが動作していたことを確認するためにテストしたプリントをコメントアウトしました。リストのヒープのアルゴリズムの実装

私の現在のコード:

public static ArrayList<int[]> lists = new ArrayList<>(); 

public static void main(String[] args) { 
    int[] list = {1,2,3,4}; 
    heapsAlgorithm(4,list); 
    for(int i = 1; i <= lists.size(); i++) { 
     System.out.println("List " + i + ": " + Arrays.toString(lists.get(i-1))); 
    } 
} 

public static void heapsAlgorithm(int n, int[] list) { 
    if (n == 1) { 
     lists.add(list); 
     //System.out.println(Arrays.toString(list)); 
    } 
    else { 
     for(int i = 0; i < n; i++) { 
      heapsAlgorithm(n - 1, list); 
      if (n % 2 == 0) { 
       int swap = list[i]; 
       list[i] = list[n-1]; 
       list[n-1] = swap; 
      } 
      else { 
       int swap = list[0]; 
       list[0] = list[n-1]; 
       list[n-1] = swap; 
      } 
     } 
    } 
} 

ワーキング:

[1, 2, 3, 4] 
[2, 1, 3, 4] 
[3, 1, 2, 4] 
[1, 3, 2, 4] 
[2, 3, 1, 4] 
[3, 2, 1, 4] 
[4, 2, 3, 1] 
[2, 4, 3, 1] 
[3, 4, 2, 1] 
[4, 3, 2, 1] 
[2, 3, 4, 1] 
[3, 2, 4, 1] 
[4, 1, 3, 2] 
[1, 4, 3, 2] 
[3, 4, 1, 2] 
[4, 3, 1, 2] 
[1, 3, 4, 2] 
[3, 1, 4, 2] 
[4, 1, 2, 3] 
[1, 4, 2, 3] 
[2, 4, 1, 3] 
[4, 2, 1, 3] 
[1, 2, 4, 3] 
[2, 1, 4, 3] 

誤った出力:

List 1: [4, 1, 2, 3] 
List 2: [4, 1, 2, 3] 
List 3: [4, 1, 2, 3] 
List 4: [4, 1, 2, 3] 
List 5: [4, 1, 2, 3] 
List 6: [4, 1, 2, 3] 
List 7: [4, 1, 2, 3] 
List 8: [4, 1, 2, 3] 
List 9: [4, 1, 2, 3] 
List 10: [4, 1, 2, 3] 
List 11: [4, 1, 2, 3] 
List 12: [4, 1, 2, 3] 
List 13: [4, 1, 2, 3] 
List 14: [4, 1, 2, 3] 
List 15: [4, 1, 2, 3] 
List 16: [4, 1, 2, 3] 
List 17: [4, 1, 2, 3] 
List 18: [4, 1, 2, 3] 
List 19: [4, 1, 2, 3] 
List 20: [4, 1, 2, 3] 
List 21: [4, 1, 2, 3] 
List 22: [4, 1, 2, 3] 
List 23: [4, 1, 2, 3] 
List 24: [4, 1, 2, 3] 

私は私のArrayListが間違って使用していますと仮定し、私はどこか分かりません。助言がありますか?

+1

配列のコピーをリストに追加する必要があります: 'lists.add(Arrays.copyOf(list、list.length))'。 –

+0

ありがとう!それはうまくいった。配列を直接追加するのではなく、配列のコピーを追加する理由は何ですか? –

+0

リストに配列(または何か、一般的に)を追加してもそれがコピーされるわけではないので、単に参照を格納しているだけです。したがって、リストの「外側」の配列への更新は、リスト内の同じ配列への更新でもあります。 –

答えて

1

int配列をコピーする必要があります。

あなたは配列の可変インスタンスと、順列を保つことを前提とした配列のリストを持っています。基本的に、何が起こっているのですか:

  1. あなたは順列をします。
  2. ArrayListに順列を追加します。
  3. あなたはSAMEオブジェクトで別の並べ替えを行います。
  4. このリストの中に既に存在するArrayListにオブジェクトを追加します。

最後に、同じint配列が20回追加されたArrayListがあります。

関連する問題