简体   繁体   English

程序中查找素数的循环问题

[英]Trouble with loops in a program to find prime numbers

Hi I have been having a problem working out how to get this to work. 嗨,我一直在解决如何使它起作用的问题。 It's intended to find the first x number of prime numbers using a user input to set x. 旨在使用用户输入来设置x的第一个x个质数。 It will then place any in an array before printing the results. 然后,它将在打印结果之前将它们放置在数组中。 I think I have made an issue with the loops as once the user input is entered nothing will happen. 我想我在循环方面遇到了问题,因为一旦输入用户输入,就不会发生任何事情。 I'd be grateful if anyone could maybe point out where I have gone wrong and provide suggestions on how to fix it. 如果有人能指出我哪里出了问题并提供有关如何解决它的建议,我将不胜感激。 Thanks 谢谢

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() + ", ");
        }
    }

First of all, that's not the way to test if a number is a prime number, but then again, the cycle is all wrong. 首先,这不是测试数字是否为质数的方法,但是再次,循环都是错误的。

If you put a max which is higher that the number of prime numbers less than 9999 it will cycle in the outer loop forever. 如果您输入的最大值大于小于9999的质数,它将永远在外循环中循环。

Check the wiki for some first insights: http://en.wikipedia.org/wiki/Primality_test 检查Wiki以获得一些初步见解: http : //en.wikipedia.org/wiki/Primality_test

To check my statement you could add some console output in the outer loop and see for yourself 要检查我的声明,您可以在外循环中添加一些控制台输出并亲自查看

In the spirit of trying to keep to your original code, here is an adjusted take on your algorithm, modified to use the Sieve of Eratosthenes : 本着尝试保持原始代码的精神,以下是对算法的调整后的修改,以使用EratosthenesSieve进行修改:

  • The Sieve can iteratively determine all primes, with only the knowledge that 2 is a prime. 筛选器可以迭代确定所有素数,而仅需知道2是素数。
  • The exit condition on the inner loop should be when the we exceed the square root of the number we are testing, with our list of known primes (not 9999 and break ). 内循环的退出条件应该是当我们超过我们正在测试的数字的平方根时,带有我们已知的素数列表(不是9999break )。 Because of the definition of a prime number, with a list of prime numbers up to X, we can resolve all other prime numbers up to X * X. (So we can stop testing if we exceed the square root eg 2 can resolve 3 and 4, 2 and 3 can resolve up to 9, etc). 由于定义了质数,带有最多X的质数列表,我们可以解析所有其他质数,直到X *X。(因此,如果超过平方根,我们可以停止测试,例如2可以解析3, 4、2和3最多可以解析9,依此类推)。 This is also because our primes are already ordered in ascending order. 这也是因为我们的素数已经按升序排序。
  • I've kept the original variables, ie count is the next tested candidate prime, i is the current index of the prime, max is upper bound to populate. 我保留了原始变量,即count是下一个测试的候选素数, i是素数的当前索引, max是要填充的上限。
  • The first prime, 2, needs to be hard coded (ie primes[0] = 2 , the next prime index i will be 1, and the first candidate number we need to check thereafter will be 3. 第一个素数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++;
}

As per @Massimo's link, the above brute force mechanism is terribly inefficient. 根据@Massimo的链接,上述蛮力机制效率极低。 An improvement is the 'wheel of 6' referenced in the Wiki article - after count=6 , the wheel of 6 takes each candidate set of numbers to test in batches of 6, and all multiples of 2 and 3 can immediately be eliminated. 一个改进是Wiki文章中引用的“ 6的转轮”-在count=6count=6的转轮将每个候选数字集以6的批次进行测试,并且可以立即消除2和3的所有倍数。 Other larger wheels are also possible. 其他较大的车轮也是可以的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM