2017-09-02 23 views
1

我写了一个代码,返回两个素数,其间隙等于给定的long,并且它们之间没有其他素数。进一步优化我的Java代码充满for-loops

这是迄今为止我所做的方法:

public static long[] firstGap(int gap, long lLimit, long uLimit) { 
    for(long i=lLimit; i<=uLimit; i++) { 
     for(long j=i+1; j<=uLimit; j++) { 
      if(isPrime(i) && isPrime(j) && j-i==gap && !repeatedIsPrime(i+1,j-1)) { 
       return new long[]{i,j}; 
      } 
     } 
    } 
return null; 
} 

为了检查一个数是否为素

public static boolean isPrime(long n) { 
    for(int i=2;i<n;i++) { 
     if(n%i==0) { 
      return false; 
     } 
    } 
return true; 
} 

为了检查是否有两个数字

public static boolean repeatedIsPrime(long x, long y) { 
    for(long i=x; i<=y; i++) { 
     if(isPrime(i)) { 
      return true; 
     } 
    } 
return false; 
} 
之间的质数

我到目前为止所做的工作是将循环索引作为int,但然后我会有一个有损转换,接下来是r引发方法调用,但我找不到一种方法来做到这一点。到目前为止,我所做的唯一改进就是删除了一些不必要的存储和赋值,除此之外我什么都没有。那么我如何进一步优化我的代码呢?

+0

您可以通过首先改进算法来大大提高此程序的速度。减少方法调用不会使代码更快。 – pvg

回答

1

您可以使用下面的代码:

public static long[] firstGap(int gap, long lLimit, long uLimit) { 
    for(long i=lLimit; i<=uLimit; i++) { 
     if(isPrime(i)) { 
      long j = gap + i; 
      if (isPrime(j) && !repeatedIsPrime(i + 1, j - 1)) { 
       return new long[]{i, j}; 
      } 
     } 
    } 
    return null; 
} 

首先,如果isPrime(I)==假的,其他的检查没有任何意义。其次,for(long j=i+1; j<=uLimit; j++)可以删除,因为你只使用一名的J(当姬==间隙)

1
  1. 拆下内循环:`如果(isPrime(I)& & isPrime(1 +间隙)& & repeatedIsPrime (i + 2,i + gap-2)返回新的long [] {i,j}
  2. 确保lLimit和uLimit是奇数并加2作为无意义来检查偶数
  3. 检查素数,运行直到n的平方根
  4. 可以使用HashMap < Long,Boolean>确保你只有检查相同的号码 - 但移动时必须删除最小号码
  5. 使用更智能的素性测试,例如,费马测试https://en.wikipedia.org/wiki/Primality_test#Fermat_primality_test isPrime(i)