我正在尝试解决Project Euler难题46。在此难题中,您必须找到第一个不能由素数和平方的和得出的复合数。
为解决问题,我遍历所有奇数,检查它们是否为质数,如果不是,则遍历数字以下的所有质数,以检查差是否为平方的两倍。
我正在使用两个for循环来执行此操作,由于某种原因,遍历素数的for循环会引发参数超出范围异常。
我不知道为什么会引发此错误,因为for循环不应允许这种情况发生。
这是我的代码:
using System;
using System.Collections.Generic;
namespace Challenge_46
{
class Program
{
/*
* Task -
* It was proposed by Christian Goldbach that every odd composite number can be written as the sum of a prime and twice a square.
* 9 = 7 + 2 × 1^2
* 15 = 7 + 2 × 2^2
* 21 = 3 + 2 × 3^2
* 25 = 7 + 2 × 3^2
* 27 = 19 + 2 × ^22
* 33 = 31 + 2 × 1^2
*
* It turns out that the conjecture was false.
*
* What is the smallest odd composite that cannot be written as the sum of a prime and twice a square?
*/
static void Main(string[] args)
{
List<int> primes = new List<int>() { 3 }; // We do not need 2 been as an odd number minus an even number is odd, which cannot be 2 times a square
bool notFound = true;
for (int i = 5; notFound == true; i += 2 )
{
if (IsPrime(i, primes))
{
primes.Add(i);
continue;
}
for (int j = 0; primes[j] < i && j < primes.Count; j++)
{
if (!(IsSquare( (i - primes[j]) / 2)))
{
notFound = false;
}
else
{
notFound = true;
break;
}
}
if (notFound == false)
{
Console.WriteLine("The first composite number that cannot be written as the sum of a prime and twice a square is {0}", i);
}
}
}
static bool IsSquare(int n)
{
if (Math.Sqrt(n) == Math.Floor(Math.Sqrt(n))) // if the square root is an integer
{
return true;
}
else
{
return false;
}
}
static bool IsPrime(int n, List<int> primes)
{
foreach (int prime in primes)
{
if (n % prime == 0)
{
return false;
}
}
return true;
}
}
}
我们将不胜感激。
谢谢。
答案 0 :(得分:3)
您的错误是由for条件下出口评估的顺序引起的。条件是从左到右评估的,因此代码首先评估条件primes[j] < i
,只有在此之后,代码才会检查j < primes.Count
,但这不会保护第一个评估在j时超出范围等于素数。计数。
修复很容易,只需交换两个条件即可。首先检查您是否仍在范围内,然后检查其他情况
for (int j = 0; j < primes.Count && primes[j] < i; j++)