【问题标题】:Trouble with loops in a program to find prime numbers程序中查找素数的循环问题
【发布时间】:2015-06-07 09:56:36
【问题描述】:

您好,我一直在想办法让它发挥作用时遇到问题。它是 旨在使用用户输入来设置 x 来查找前 x 个素数。然后它将在打印结果之前将任何放入数组中。我想我对循环提出了问题,因为一旦输入用户输入,什么都不会发生。如果有人能指出我哪里出错并提供如何解决它的建议,我将不胜感激。谢谢

static void Main(string[] args)
    {
        int max, i, count;
        i = 0; // this is used to keep trck of how many primes have been added to the array
        count = 0; // this is used to test each number
        Console.WriteLine("This will work out the first x prime numbers with x being the number of prime numbers you want");
        Console.WriteLine("Enter the number of prime numbers you want.");
        max = Convert.ToInt32(Console.ReadLine());

        int[] primes = new int[max];

        while (i <= max)
        {
         while (count <= 9999)
         {
             if (count % 2 == 0 || count % 3 == 0 || count % 5 == 0 || count % 7 == 0 ) // tests if count number is a prime 
             {
                 if (count == 2 || count == 3 ||count == 5 ||count == 7 ) // ensures 2,3,5,7 are added to primes if neccesarry
                 {

                     primes[count] = count; //add to array
                     i++; // increments the count on the number of prime numbers
                 }
                 count ++; // increments the count 
                 break;
             }
             else
             {
                 primes[count] = count;
                 i++;
                 count ++;
             }
         }
        }

        Console.WriteLine("The first {0} prime numbers are ... ", max);
        foreach(var item in primes)
        {
            Console.Write(item.ToString() + ", ");
        }
    }

【问题讨论】:

  • 计算测试 121 (=11*11) 时会发生什么。它不能被 2,3,5 或 7 整除...

标签: c# loops console-application nested-loops


【解决方案1】:

首先,这不是测试一个数是否为质数的方法,但话说回来,循环都是错误的。

如果你设置的最大值高于小于 9999 的素数的数量,它将永远在外循环中循环。

查看 wiki 以获得一些初步见解:http://en.wikipedia.org/wiki/Primality_test

要检查我的陈述,您可以在外循环中添加一些控制台输出并自己查看

【讨论】:

    【解决方案2】:

    本着努力保持原始代码的精神,这里是对您的算法的调整,修改为使用Sieve of Eratosthenes

    • Sieve 可以迭代确定所有素数,只需知道 2 是素数。
    • 内部循环的退出条件应该是当我们超过我们正在测试的数字的平方根时,我们的已知素数列表(不是9999break)。由于素数的定义,使用最多为 X 的素数列表,我们可以解析最多为 X * X 的所有其他素数。(因此,如果我们超过平方根,我们可以停止测试,例如 2 可以解析 3 和4、2 和 3 最多可以解析 9 个等)。这也是因为我们的素数已经按升序排列。
    • 我保留了原始变量,即count 是下一个测试的候选素数,i 是素数的当前索引,max 是要填充的上限。
    • 第一个素数 2 需要硬编码(即 primes[0] = 2,下一个素数索引 i 将是 1,之后我们需要检查的第一个候选数将是 3。

    // We do need to hard code that 2 is a prime number. Everything else can be derived
    primes[0] = 2;
    i = 1;
    count = 3;
    
    // i.e. stop when we get the required number of primes
    while (i < max)
    {
        // Indicator to stop testing this candidate if we find a factor
        bool foundFactor = false;
        // Start off each primality test from the start of our primes array
        var primeIndex = 0;
    
        // Try and find a factor of 'count' with our known primes
        while (!foundFactor && primeIndex < i)
        {
            // We can stop after the square root. Multiplication is faster than sqrt
            if (primes[primeIndex]*primes[primeIndex] > count)
                break;
            // If the candidate number
            if (count % primes[primeIndex] == 0)
                foundFactor = true;
            primeIndex++;
        }
        if (!foundFactor)
        {
            primes[i] = count;
            i++;
        }
    
        count++;
    }
    

    根据@Massimo 的链接,上述蛮力机制非常低效。改进是 Wiki 文章中提到的“6 之轮”——在count=6 之后,6 之轮将每个候选数字集以 6 为一组进行测试,并且可以立即消除所有 2 和 3 的倍数。其他更大的轮子也是可能的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-31
      • 2016-05-02
      • 2020-10-07
      • 1970-01-01
      相关资源
      最近更新 更多