找到第10001个素数

时间:2016-10-23 17:03:09

标签: c# primes

我看了项目euler的以下问题:

通过列出前六个素数:2,3,5,7,11和13,我们可以看到第6个素数是13。 什么是10 001主数?

我试图取数字的平方根,然后找到数字平方根下面的所有素数,然后将数字除以所有平方根,看每次是否有0。如果该数字不能被其平方根下的所有素数整除,则为素数。我这样做是为了降低程序必须进行的迭代。这就是我现在所拥有的,我不知道为什么它不起作用。谁知道我做错了什么?

  List<int> primeNumbers = new List<int>();
        bool prime = true;
        bool MainPrime = true;
        int check = 1;
        for (long i = 3; i < long.MaxValue; i++)
        {
            if ((i % 2) != 0)
            {
                int root = Convert.ToInt32(Math.Sqrt(i));
                for (int j = 1; j < root; j++)
                {
                    for (int k = 2; k < j; k++)
                    {
                        if ((j% k) == 0)
                        {
                            prime = false;
                        }
                    }
                    if (prime)
                    {
                        primeNumbers.Add(j);
                    }
                    prime = true;
                }

            }
            foreach (var item in primeNumbers)
            {
                if ((i%item) == 0)
                {
                    MainPrime = false;
                }
            }
            primeNumbers.Clear();
            if (MainPrime)
            {
                check++;
            }
            if (check == 10001)
            {
                Console.WriteLine(i);
                break;

            }
        }

        Console.ReadKey();

2 个答案:

答案 0 :(得分:3)

有几点:

  1. 在找到可能的主要除数时,您需要检查所有数字,直到包含的平方根,因此您的条件j < root不正确。

  2. 您不必为每个号码重新计算素数。随时保留列表并添加新的素数。

  3. 一旦找到除数,就可以摆脱foreach循环。

  4. 改进代码:

    List<long> primeNumbers = new List<long>() { 2 };
    for (long i = 3; i < long.MaxValue; i += 2)
    {
        if(!primeNumbers.Any(p => (i % p) == 0))
        {
            primeNumbers.Add(i);
            if (primeNumbers.Count == 10001)
            {
                Console.WriteLine(i);
                break;
            }
        }
    }
    

    将104743作为第10001个素数。

答案 1 :(得分:0)

我们可以做的是我们可以使用 SieveOfEratosthenes 制作一个 bool 数组,其中所有素数值都设置为真;

1.当我们发现任何素数时,计数加 1;

2.当 count 等于 10001 时,我们打印它的值并打破循环。

看看 C++ 中的代码(我建议你先学习 SieveOfEratosthenes)

#include <bits/stdc++.h>
using namespace std;
void SieveOfEratosthenes(long long unsigned n)
{
    bool prime[n];
    memset(prime, true, sizeof(prime));                //This is SieveOfEratosthenes
 
    for (long long  p = 2; p * p <= n; p++)
    {
        if (prime[p] == true) 
        {
            for (long long  i = p * p; i <= n; i += p)      
                prime[i] = false;                         
        }
    }
    
    
    long long count=0;                      //initializing count as 0;
    for (long long  p = 2; p <= n; p++)       //running the loop form 2 to n
       {
         if (prime[p])                      //we have bool array in which all prime number set to true using sieve
           count++;                         //increment the count because we found a prime number 
           if(count==10001)                 // and as count reaches to 10001 we found our number 
           {
           cout<<p;break;}                 // print the answer and also break form the loop
        }
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    long long unsigned n=999999;
    SieveOfEratosthenes(n);     //pass the value of n in sieve function
    return 0;
}