【问题标题】:Find the 10001st prime找到第 10001 个素数
【发布时间】:2016-10-23 17:03:08
【问题描述】:

我看了一下来自project euler的以下问题:

通过列出前六个素数:2、3、5、7、11 和 13,我们可以看到第 6 个素数是 13。 第10001个质数是多少?

我尝试取数字的平方根,然后找到数字平方根下方的所有质数,然后将数字除以所有平方根,看看是否每次都剩下 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();

【问题讨论】:

    标签: c# primes


    【解决方案1】:

    几点:

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

    2. 您不必为每个数字重新计算素数。随时保留列表并向其中添加新素数。

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

    改进的代码:

    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 个素数。

    【讨论】:

    • 非常感谢,还在学习中:P。你能向我解释一下 => 吗?我读过它,它是一个 lambda 表达式或其他东西。但我从文档中无法完全理解。
    • @Mathijs => 运算符分隔 lambda 表达式的输入和输出。这是 MSDN 上的指南:msdn.microsoft.com/en-us/library/bb397687.aspx
    • 那么=>基本上左边有参数,右边有“方法”?
    【解决方案2】:

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

    1.我们发现任何素数都将计数加 1;

    2.当计数等于 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;
    }
    

    【讨论】:

      【解决方案3】:

      用python试试这个

      sp=2
      cnt = 1
      while cnt <= 10001:
          primeflag = 0
          for j in range(2,sp):
              if(sp%j == 0):
                  primeflag = 1
                  break;
          if(primeflag == 1):
              pass
          else:
              print(cnt ,sp)
              cnt = cnt +1
          sp =sp+1
          
      

      #给 #10001 104743

      【讨论】:

      • 但问题被标记为 C#。这对他们有什么帮助?
      猜你喜欢
      • 2018-12-29
      • 2016-09-15
      • 2015-11-26
      • 1970-01-01
      • 1970-01-01
      • 2013-01-22
      • 1970-01-01
      • 2016-02-01
      • 1970-01-01
      相关资源
      最近更新 更多