Java &引用;是素数;算法运行时

Java &引用;是素数;算法运行时,java,algorithm,Java,Algorithm,我试图用最快的算法来找出一个数是否是素数。 我对从3到100000的每个数字都这样做 for(int i = 3; i < 100000; i += 1) if(isPrime(i)) System.out.println(i); for(int i=3;i

我试图用最快的算法来找出一个数是否是素数。 我对从3到100000的每个数字都这样做

   for(int i = 3; i < 100000; i += 1)
        if(isPrime(i))
            System.out.println(i);
for(int i=3;i<100000;i+=1)
如果(i)
系统输出打印LN(i);
需要0.52秒。 我的朋友建议不要迭代偶数:

for(int i = 3; i < 100000; i += 2)
        if(isPrime(i))
            System.out.println(i);
for(int i=3;i<100000;i+=2)
如果(i)
系统输出打印LN(i);
这需要0.53秒(可能是随机差异)

为什么他的建议不能减少运行时间? 如果我遍历更少的数字,我希望程序运行得更快

isPrime()的代码:

public静态布尔值isPrime(int n)
{
如果((n%2==0&&n!=2)| |(n%3==0&&n!=3)| |(n%5==0&&n!=5))
返回false;
对于(int i=5;i
除了算法问题,您的瓶颈很可能是写入
系统.out
流。这是一项耗时的任务,我认为您应该将该部分从基准循环中删除。要快速测试这一点,只需将其注释掉(使用相应的
if
语句):

这有什么问题
Math.sqrt
是一项成本高昂的操作。比乘法要昂贵得多。。。因此,如果数字范围允许(您必须始终记住!),我们可以使用乘法更快地进行比较:

sqrt(a)>b==a*a>b
假设a和b都是正整数

    Integer currentPrimeSquare = primeList.get(i)*primeList.get(i);
    if(currentPrimeSquare>numberTested) {
        //still not found a divider -- we found a prime
        primeList.add(numberTested);
        break;
    }

为了进一步调整,您也可以存储素数的平方-如果您有足够的内存…

很可能需要大量时间将素数打印到控制台。因此,如果素数的数量没有减少,那么减少测试的数量不会显著影响程序的速度

尝试将素数收集到字符串中并打印一次,如下所示:

StringBuilder b = new StringBuilder();
for(int i = 3; i < 100000; i += 1)
    if(isPrime(i))
      b.append(i).append("\n");

System.out.println(b.toString());
StringBuilder b=新的StringBuilder();
对于(int i=3;i<100000;i+=1)
如果(i)
b、 附加(i).附加(“\n”);
System.out.println(b.toString());
也许这篇文章可以帮助您:

boolean isPrime(int n) {
//check if n is a multiple of 2
if (n%2==0) return false;
//if not, then just check the odds
for(int i=3;i*i<=n;i+=2) {
    if(n%i==0)
        return false;
}
return true;
}
布尔isPrime(int n){
//检查n是否为2的倍数
如果(n%2==0)返回false;
//如果没有,那就检查一下赔率

例如(int i=3;i*i在比较java运行时,需要担心VM本身的开销(例如,println在每次执行时可能需要不同的时间段)。要获得正确的运行时比较,请将每个运行时运行1000次,并获得更准确结果的平均值


同样,在java中实现并不是那么困难,它会给你很快的结果,尽管它会使用更多的内存。

如果你对已知的最有效的算法感兴趣,知道给定的数是否是素数,你应该考虑读关于多对数时间的读数。

(这个答案基本上是对素数测试的一个重复)。 2) 你不应该用运行时间来衡量效率

3) 中的if语句是prime,如果您正在检查is
n={2,3,5}
则使用它返回结果,这将阻止您执行其余代码(在这种情况下不会节省太多时间)


4) 对于for循环,您可以为i从7(您已经检查了5的条件,6不是质数)到sqrt(n)

参见相关问题使用seving查找sqrt(MAX_输入)的质数,并测试从2到sqrt(MAX_输入)的所有质数。但如果你在大范围内搜索素数,那么只需输入最大值即可。@nhahdh我知道这个解决方案,但我可以问一下为什么它有用吗?@shohamh:它工作更少,所以速度更快。(我在这里只讨论算法。在这种情况下,打印可能比算法本身花费更多时间)@RudolphEst:现在测试100000个数字算不了什么。写入控制台是一个更大的问题……但是
System.out
在OP的两种情况下仍然存在。@Nishantshresh这就是为什么我提到“将该部分从基准循环中剔除”.1这解释了
System.out
可能对输出产生的影响。这是如何解决实际问题的?你知道,OP文本后面带有问号的部分?这个“改进”版本报告2不是质数。速度与给出错误答案无关。。。
    Integer currentPrimeSquare = primeList.get(i)*primeList.get(i);
    if(currentPrimeSquare>numberTested) {
        //still not found a divider -- we found a prime
        primeList.add(numberTested);
        break;
    }
StringBuilder b = new StringBuilder();
for(int i = 3; i < 100000; i += 1)
    if(isPrime(i))
      b.append(i).append("\n");

System.out.println(b.toString());
boolean isPrime(int n) {
//check if n is a multiple of 2
if (n%2==0) return false;
//if not, then just check the odds
for(int i=3;i*i<=n;i+=2) {
    if(n%i==0)
        return false;
}
return true;
}