C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト


(過去ログ 43 を表示中)
■22651 / )  yield returnに関して
□投稿者/ foo (3回)-(2008/07/29(Tue) 11:49:06)

分類:[C#] 

たびたびお世話になっています。
前回、Rubyのeachに関してスレッドを立てた者です。
http://bbs.wankuma.com/index.cgi?mode=al2&namber=22630
今回もその続きです。

おかげさまで疑問が解決して、以下のようにC#に翻訳しました。

class PowerSetGenerator
{
 int[] _set;

 public PowerSetGenerator(int[] set)
 {
  _set = set;
 }

 public List<List<int>> GetPowerSet()
 {
  List<List<int>> ret = new List<List<int>>();

  int nElem = (int)Math.Pow(2, _set.Length);
  for (int i = 0; i < nElem; i++)
  {
   int n = i;
   List<int> a = new List<int>();

   // 前回質問したところ
   foreach (int m in _set)
   {
    if (1 == (n & 1)) a.Add(m);
    n >>= 1;
   }
   ret.Add(a);
  }
  return ret;
 }
}

集合がn個の要素からなるとき、その集合から作るべき集合の要素は2^n個になります。
なので、GetPowerSetを実行すると戻り値が物凄い量のメモリを消費してしまいますね。(intなので高が知れてますが...

そんなときに知ったのがyield return。
以下のように書き換えれば、べき集合を一気に作ってしまわずに小出しにできるのではと思ったのですが、そもそも使用方法は合っているのでしょうか。
私が期待しているような動きになっているのでしょうか。
(と言っても、「私が期待している動き」というものを説明できていませんが。)
class PowerSetGenerator
{
 int[] _set;

 public PowerSetGenerator(int[] set)
 {
  _set = set;
 }

 public IEnumerable<List<int>> GetPowerSet()
 {
  int nElem = (int)Math.Pow(2, _set.Length);
  for (int i = 0; i < nElem; i++)
  {
   int n = i;
   List<int> a = new List<int>();

   foreach (int m in _set)
   {
    if (1 == (n & 1)) a.Add(m);
    n >>= 1;
   }
   yield return a;
  }
 }
}

実行したら一応どちらも同じになりました。
返信 編集キー/


管理者用

- Child Tree -