我正在研究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;
}
}
答案 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,因为纯粹的因子分解可能会让你相信。