优化递归方法

时间:2014-10-19 20:24:43

标签: java optimization recursion

我有一些代码需要运行一些相当大的数字,并且它涉及递增到递归方法,因此非常慢到我甚至无法得到我想要的答案。有人可以帮我优化吗?我是初学者,所以我不能做任何非常复杂/困难的事情。

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;
    }
 } 

2 个答案:

答案 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>