【问题标题】:Improving 10001st prime number project改进第10001个素数项目
【发布时间】:2014-03-07 20:02:51
【问题描述】:

我一直在研究一个 Project Euler 问题,即找到第 10001 个素数。我用java制作了这个项目,它给了我正确的答案。我不禁注意到,找到答案花了 17 秒。我对 java 还很陌生,我希望得到有关如何提高我的 Java 程序效率的反馈——目前它是蛮力的。

static boolean isPrime;  
static int primeCount;  
static int forI = 1;  
static int latestPrime;  

public static void main(String[] args){  
    long startTime = System.currentTimeMillis();  
    while(primeCount < 10001){  
        isPrime = true;  
        forI++;  
        for(int i = forI - 1; i > 1; i--){  
            //If forI is divisible by another number < forI, it is not prime  
            if(forI % i == 0){  
                isPrime = false;  
            }  
        }  
        if(isPrime){  
            primeCount++;  
            latestPrime = forI;  
        }  
    }  
    long endTime = System.currentTimeMillis() - startTime;  
    System.out.println(primeCount+" "+latestPrime);  
    System.out.println("Time taken: " + endTime / 1000 + " seconds");  
}  

【问题讨论】:

  • a) 当你找到一个除数时,你不会中止你的 for() 循环,所以你继续测试所有其他可能的除数,浪费时间。 b)您正在为每个数字测试太大的范围 - 您只需要测试到 sqrt(number_being_tested)。您正在测试所有可能的除数,包括偶数。 c) 由于 2 是唯一的偶素数,因此所有其他偶数除数都是不可能的。
  • 澄清@MarcB 的“a)”:将for-loop 标头更改为for(int i = forI - 1; i &gt; 1 &amp;&amp; isPrime; i--){...我认为isPrime,而不是!isPrime...
  • 请去掉项目欧拉问题的答案!此外,这个问题对于 stackoverflow 来说似乎是题外话——但对于 codereview 堆栈来说可能是题外话。
  • @MarcB 谢谢,我本来打算跳出 for 循环,但忘记了,我会加进去的。有没有更好的、非暴力的方法,或者这会是被认为是“好的做法”?
  • 您也可以查看关于问题 7 的论坛(在问题的右侧(如果您解决了问题))。讨论了许多智能且有用的优化。

标签: java primes


【解决方案1】:

您需要查看Sieve of Eratosthenes

基本上,对于每个数字,您通过检查每个小于它的单个数字来检查它是否是素数,这是非常低效的。

为了方便改进,您只需要检查所有小于数的平方根的除数。

【讨论】:

  • 这个答案充其量是不完整的,最坏的情况是它具有误导性。所链接的算法在概念和实现上都与 OP 实现的算法截然不同。这不仅仅是检查“直到平方根”的问题。这是公然错误的。
【解决方案2】:
import java.util.Scanner;
public class NewNthPrime{
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        boolean flag = false;
        int max = 10002;
        int[] a = new int[max];
        a[0] = 2;
        int i = 3,j=0;
        int t = in.nextInt();
        for(int a0 = 0; a0 < t; a0++){
            int n = in.nextInt();
            while(j<n){
                for(int y=0;y<a.length;y++){
                    if(a[y]==0){
                        break;
                    }
                    else if (i%a[y]==0){
                        flag = true;
                        break;
                    }
                }
                if(!flag){
                    a[++j]=i;
                }
                flag =false;
                i+=2;
            }
            System.out.println(a[n-1]);
        }
    }
}

【讨论】:

  • 请解释您的代码的作用、工作原理以及预期的用户输入。
猜你喜欢
  • 1970-01-01
  • 2018-12-29
  • 2015-11-26
  • 1970-01-01
  • 2016-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多