我可以更快找到perfect numbers吗?我试图用数组和另一种算法让它更快,但没有一种能让它更快。
public class Perfect{
static long perfectNumber;
static long startTime = System.nanoTime();
static long endTime;
static long mersenne;
public static void main(String[] args) {
long p = 2;
while (p < 32) {
if( p % 2 == 0&&p!=2){
p++;
}
else{
if (isPrime(p) == true) {
mersenne = (long) (Math.pow(2, p) - 1);
if (isPrime(mersenne) == true) {
perfectNumber = (long) Math.pow(2, (p - 1)) * mersenne;
System.out.println(perfectNumber);
}
}
p++;
}
}
endTime = System.nanoTime();
System.out.println("Time: " + (endTime - startTime) + "ns"
);
}
private static boolean isPrime(long testPrime) {
for (long i = 3; i < Math.sqrt(testPrime); i += 2) {
if (testPrime % i == 0) {
return false;
}
}
return true;
}
}
答案 0 :(得分:0)
您可以进行一些小的改进 - 可能没有一个会对运行时间产生任何影响:
p % 2
可能导致分割 - p & 1
不会,因此应该快一点。Math.pow(2,x)
与2 << x
等效,可能会更快。除了那些微不足道的,可能是过早的优化之外 - 你应该运行几百次计算,并在尝试任何优化之前花费平均时间。
顺便说一句 - 仅仅因为你使用nanotime
并不意味着你得到了纳秒分辨率 - 远非它。
另外 -
正如维基百科的文章指出的那样 - 你可以通过列举那里提到的常见二进制模式来避免大部分计算:
for ( int i = 0; i < 10; i++ ) {
long q = ((1 << (i+2)) - 1) << (i+1);
// Printing BigIntegers in binary is easy.
BigInteger bq = BigInteger.valueOf(q);
System.out.println(q+" = "+bq.toString(2));
}
6 = 110
28 = 11100
120 = 1111000
496 = 111110000
2016 = 11111100000
8128 = 1111111000000
32640 = 111111110000000
130816 = 11111111100000000
523776 = 1111111111000000000
2096128 = 111111111110000000000
显然你仍然需要测试它们,但你不必测试几乎那么多。
另外 - 如果你想进一步进入BigInteger
,你可以从以下内容开始:
for ( int i = 0; i < 10; i++ ) {
BigInteger p = BigInteger.ONE.shiftLeft(i+2).subtract(BigInteger.ONE).shiftLeft(i+1);
System.out.println(p.toString(10)+" = "+p.toString(2));
//long q = ((1 << (i+2)) - 1) << (i+1);
//BigInteger bq = BigInteger.valueOf(q);
//System.out.println(" "+bq.toString(10)+" = "+bq.toString(2));
}