ほかに実用的な使い道は思いつかなかったけど、使いこなせれば便利なのかな?
using System;
using System.Collections.Generic;
using System.Text;
namespace YieldSample
{
class Program
{
static void Main(string[] args)
{
int n;
n = 0;
foreach (int p in Prime())
{
++n;
if (n == 100000)
{
Console.WriteLine(string.Format("{0}番目の素数:{1}", n, p));
break;
}
}
n = 0;
foreach (int p in Prime())
{
++n;
if (n == 1000000)
{
Console.WriteLine(string.Format("{0}番目の素数:{1}", n, p));
break;
}
}
}
static List aPrime = new List();
public static IEnumerable Prime()
{
// 最初の素数 2
if (aPrime.Count == 0)
{
aPrime.Add(2);
}
yield return 2;
// 以降、素数候補を 3から始めて 2ずつ加算しながら検証する
int np = 1; // 出力済みの素数順位
int next = 3; // 次の素数候補
while (true)
{
if (np < aPrime.Count)
{
// 既に作成済みの素数を出力する
yield return aPrime[np];
next = aPrime[np] + 2;
++np;
}
else
{
// 次の素数を見つけてリストに追加&出力する
foreach (int prime in aPrime)
{
if ((Int64)next < (Int64)prime * prime)
{
// 因数となる素数がなかったので新しくリストに追加して出力する
aPrime.Add(next);
yield return next;
++np;
break;
}
if (next % prime == 0)
{
// 因数となる素数があったため次の素数候補を検証する
break;
}
}
next += 2;
}
}
}
}
}