我有一些代码需要运行一些相当大的数字,并且它涉及递增到递归方法,因此非常慢到我甚至无法得到我想要的答案。有人可以帮我优化吗?我是初学者,所以我不能做任何非常复杂/困难的事情。
public class Euler012{
public static void main(String[]args){
int divisors=0;
for(long x=1;divisors<=501;x++){
divisors=1;
long i=triangle(x);
for(int n=1;n<=i/2;n++){
if(i%n==0){
divisors++;
}
}
//System.out.println(divisors+"\n"+ i);
System.out.println(i+": " + divisors);
}
}
public static long triangle(long x){
long n=0;
while(x>=0){
n+=x;
x--;
triangle(x);
}
return n;
}
}
答案 0 :(得分:1)
首先:我不认为它是一个优化问题,因为它是一个小任务,但正如评论中提到的那样,你做了许多不必要的事情。
好的,现在让我们看看你可以优化的地方:
递归通常表现不佳,特别是如果你不保存值,这在你的例子中是可能的。
例如:具有保存值的递归三角数函数
private static ArrayList<Integer> trianglenumbers = new ArrayList<>();
public static int triangleNumber(int n){
if(trianglenumbers.size() <= n){
if(n == 1)
trianglenumbers.add(1);
else
trianglenumbers.add(triangleNumber(n-1) + n);
}
return trianglenumbers.get(n-1);
}
但正如@RichardKennethNiescior所提到的,您可以简单地使用以下公式:
(n² + n)/2
但在这里我们也可以进行优化!
你不应该/2
而是*0.5
甚至>>1
(右移)
但是大多数编译器都会为你做这些,所以不需要让你的代码不可读
public static void main(String[]args){
int divisors = 0; //skip the = 0
for(long x=1;divisors<=501;++x){ // ++x instead of x++
divisors=0;
long i=(x*x + x) >> 1; // see above, use the one you like more
/*how many divisors*/
if(i == 1) divisors = 1;
else{ /*1 is the only number with just one natural divisor*/
divisors = 2; // the 1 and itself
for(int n = 2; n*n <= i; ++n){
if(n*n == i) ++divisors;
else if(i%n == 0) divisors += 2;
}
}
System.out.println(i+": " + divisors);
}
}
++ x而不是x ++的东西被解释为here
有多少除数: 除1之外的每个数字都至少有2个除数(素数,数字本身和1) 要检查一个数字有多少除数,我们只需要找到数字的根 (例如36 - &gt;它的平方根是6) 36有9个除数(4个){1和36,2和18,3和12,4和8,6(和6)}
1和36被轻视(for(**int n = 2**)
),但计入divisors = 2
并且削减2,3和4将除数的数量增加2
如果它是一个平方数(n * n == i),那么我们加起来1
答案 1 :(得分:0)
每次都不必从头开始生成一个新的三角形数字,如果将值保存到变量中,然后在下一次迭代中将x添加到它,则根本不需要三角形方法。< / p>