项目Euler 12 - 优化

时间:2014-01-13 15:57:28

标签: java

我正在研究Project Euler Problem 12。任何人都可以提供有关如何改进我的代码的任何提示,以便它在我的一生中执行吗?

public class HighlyDivisibleTriangularNumber {

public static void main(String[] args) {
    int divisors = 0;
    int count = 1;
    while(divisors <= 501) {
        long triNum = triangularNumber(count);
        divisors = getFactors(triNum);
        System.out.println(triNum+"_"+divisors);
        count++;
    }
}

private static int getFactors(long triNum) {
    int divisors = 0;
    while(triNum > 1) {
        triNum = triNum / 2;
        divisors++;
    }
    return divisors;
}

private static long triangularNumber(int i) {
    long total = 0;
    for(int k = 1; k <= i; k++) {
        total += k;
    }
    return total;
}
}

2 个答案:

答案 0 :(得分:2)

1)三角数

您可以做的第一个(也可能是最重要的)优化是如何计算三角数。

你可以观察到第n个三角形数字(我们称之为t(n))等于n + t(n-1)。 因此,每次计算三角形数字时,您只需取三角形数字并添加n即可。这将导致天真的递归函数:

private static long triangularNumber(int i) {
    if(i == 1) return 1;
    else return i+triangularNumber(i-1);
}

但这不会提高性能......为了解决这个问题,我建议你做一些关于记忆的研究并调整我给你的功能(我不会给你答案,这是一个很好的练习)

现在,在普通计算机上,您应该在合理的时间内找到问题的答案。但它可以改善一点

2)计算除数

你计算除数的功能是错误的。你应该做的是尝试用连续的自然数除以你的数字,看看结果是否是一个自然整数。

private static int getFactors(long triNum) {
    int divisors = 0;
    for(int i = 1; i <= triNum; ++i) {
        if(triNum%i == 0) // triNum is a multiple of 1 <=> i is a divisor of triNum
          divisors++;
    }
    return divisors;
}

您甚至可以通过仅计算trinum的平方根并每次添加两个除数来改善这一点。但如果你这样做会有一个技巧,如果你决定试试这个,我会让你搞清楚。

答案 1 :(得分:0)

为什么每次都要重新计算triNum?只需每次添加差异(基本上是您的计数)。

public static void main(String[] args) {
    int divisors = 0;
    int count = 1;
    long truNum = 0;

    while(divisors <= 501) {
        triNum += count;
        divisors = getFactors(triNum);
        System.out.println(triNum+"_"+divisors);
        count++;
    }
}

此外,您计算因子的方法完全没有。您只是在搜索2的第一个幂大于给定的数字。阅读(prime)-factorization。请注意,您还需要考虑(主要)因素的组合。

示例:12

12 = 2 * 2 * 3

但是12的除数是

1, 2, 3, 4 (= 2*2), 6 (= 2*3), 12

所以总共有6个除数12而不是3,因为纯粹的因子分解可能会让你相信。