0

以下は、リスト内の要素の累乗セットを計算するために使用した 2 つのコードです。

コード 1)

 public static List<List<int>> getCpower(List<int> list)
    {
        var result = new List<List<int>>();
        for (int i = 0; i < (1 << list.Count); i++)
        { 
            var sublist = new List<int>();
            for (int j = 0; j < list.Count; j++)
            {   if ((i & (1 << j)) != 0)
                {   sublist.Add(list[j]); 
                }
            }
            result.Add(sublist); 
        }

        return result;
    }

コード 2)

public static List<List<int>> getCpower(List<int> list)
    {
        var result = new List<List<int>>();var sublist = new List<int>();
        for (int i = 0; i < (1 << list.Count); i++)
        { 
            sublist.Clear();sublist.TrimExcess();
            for (int j = 0; j < list.Count; j++)
            {   if ((i & (1 << j)) != 0)
                {   sublist.Add(list[j]); 
                }
            }
            result.Add(sublist); 
        }

        return result;
    }

最初のコードは new ステートメントを使用し、カウント 30 のリストのパワーセットを見つけようとすると、OutOfMemoryException が発生します。メモリを節約するために、Clear() と TrimExcess() を使用して、新しいステートメントを使用して初期化されたかのようにリストを取得しました。コード2で。しかし、これら 2 つのコードは異なる結果を返します。なぜこれが起こっているのかわかりません。助けてください。

次の2つの部分は同じことをしていませんか

   for(....)   
      {
       var sublist = new List<int>();
       for(......)
           {
            //some code
           }
      }

 var sublist = new List<int>();
 for(.....)
    {
      sublist.Clear();sublist.TrimExcess();
      for(.... )
      {
      //some code 
      }
    }
4

3 に答える 3

5

2 番目のコードでは、ネストされたリストが 1 つしかありません。同じサブリストを参照する複数の参照を追加していますが、これは無意味です。

最初のコードでスペースが不足している理由は、基本的に一度に大量のデータをメモリに保持しようとしているからだと考えたことはありますか?

IEnumerable<List<int>>次のように返すことを検討できます。

public static IEnumerable<List<int>> getCpower(List<int> list)
{
    for (int i = 0; i < (1 << list.Count); i++)
    { 
        var sublist = new List<int>();
        for (int j = 0; j < list.Count; j++)
        {   if ((i & (1 << j)) != 0)
            {   
                sublist.Add(list[j]); 
            }
        }
        yield return sublist;
    }
}

これは遅延評価されるようになったので、最上位のシーケンスを反復処理できますが、リストが呼び出し元によって保持されていない限り、一度に 1 つのリストしかメモリに保持されません。

于 2012-06-16T18:01:39.283 に答える
0

2 番目のコードでは、結果のリストをクリアしています。これにより、アルゴリズムの結果が変わります。すべての反復で同じリスト インスタンスを再利用しているため、結果を破棄しています。

于 2012-06-16T18:00:55.593 に答える
0

sublist2 番目のコード例では、インスタンスは 1 つしかありません。ループするたびに、同じインスタンスがクリアされ、リストに再度追加されます。理解に役立つ例を次に示します。

var sublist = new List<int> { 1, 2, 3 };
var result = new List<List<int>> { sublist };
//result[0] is now {1, 2, 3}
sublist.Clear();
//result[0] is now {}
result.Add(sublist);
//result[0], result[1], and sublist are the same instance
于 2012-06-16T18:01:17.343 に答える