プロジェクト オイラーの問題を解いていて、現在 10 位です。
まず第一に、私は他の解決策があることを知っています.現在、エラトステネスのふるいを使用して別の方法を書いています. このコードが機能しない理由を理解するために、あなたの助けが必要です。
これは私のコードです (問題は、200 万未満のすべての素数の合計を見つけることです)。素数チェック方法は問題なく機能しているように見えますが、結果は本来あるべきものよりもはるかに劣っています。
class Euler10
{
public static void Main()
{
long sum = 0; // Was originally an int. Thanks Soner Gönül!
for(int i = 1; i < 2000000; i++)
{
if (CheckIfPrime(i) == true)
sum += i;
}
System.Console.WriteLine(sum);
System.Console.Read();
}
static bool CheckIfPrime(int number)
{
if (number <= 1)
return false;
if (number == 2)
return true;
if (number % 2 == 0)
return false;
for (int i = 3; i*i < number; i += 2)
{
if ((number % i) == 0)
return false;
}
return true;
}
}
取得した数値は 1,308,111,344 で、本来あるべき数値よりも 2 桁低くなります。コードはとても単純なので、このエラーに困惑しています。
編集:合計を長くすると、数字の問題が解決しました。みんなありがとう!しかし今、私は答えとして 143042032112 を得ます: CheckIfPrime() の i*i は常に正しいとは限りません。sqrt() 関数を使用して (int キャストを補うために) 1 つ追加すると、正しい結果が得られます。正しい CheckIfPrime() 関数は次のとおりです。
bool CheckIfPrime(int number)
{
if (number <= 1)
return false;
if (number == 2)
return true;
if (number % 2 == 0)
return false;
int max = 1 + (int)System.Math.Sqrt(number);
for (int i = 3; i < max; i += 2)
{
if ((number % i) == 0)
return false;
}
return true;
}
編集 2: Ness は、コードをさらに最適化するのに役立ちました (数値の平方根を計算して i と比較するのは、i^2 を上げてから数値と比較するよりも遅くなります): 元の方法の問題は、それが取り込まれなかったことですnumber が i の正確な 2 乗であるエッジ ケースを考慮して、false ではなく true を返すことがあります。したがって、CheckIfPrime() の正しいコードは次のとおりです。
bool CheckIfPrime(int number)
{
if (number <= 1)
return false;
if (number == 2)
return true;
if (number % 2 == 0)
return false;
for (int i = 3; i*i <= number; i += 2)
{
if ((number % i) == 0)
return false;
}
return true;
}
人々に再び感謝します!