C#For循环产生索引超出范围错误

本沃恩斯

我正在尝试解决Project Euler挑战46。在此挑战中,您必须找到第一个不能由质数和平方的乘积求和的复合数。

为了解决这个问题,我遍历所有奇数,检查它们是否为质数,如果不是,则遍历数字以下的所有质数,以检查差是否为平方的两倍。

我使用两个for循环来执行此操作,由于某种原因,遍历素数的for循环抛出了Argument Out of Range Exception。

我不知道为什么会引发此错误,因为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;
        }
    }
}

帮助将不胜感激。

提前致谢。

史蒂夫

您的错误是由for条件中出口评估的顺序引起的。条件是从左到右评估的,因此代码将首先评估条件primes[j] < i,只有在此之后,代码才会检查是否j < primes.Count但不保护当j等于primes.Count时第一次评估超出范围。

修复很容易,只需交换两个条件即可。首先检查您是否仍在范围内,然后检查其他情况

for (int j = 0; j < primes.Count && primes[j] < i; j++)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章