【发布时间】:2015-12-12 00:52:44
【问题描述】:
我在 Project Euler 问题 23 - 非丰富的和上遇到了麻烦。我的代码没有给我正确的答案,我不知道它有什么问题。如果有人也可以帮助我让它运行得更快,那就太好了。
原来的问题
完美数是一个数,它的真因数之和正好等于这个数。例如,28 的因数之和为 1 + 2 + 4 + 7 + 14 = 28,这意味着 28 是一个完美数。
如果一个数 n 的真因数之和小于 n 则称为不足数,如果该数之和超过 n 则称为丰富数。
由于12是最小的丰富数,1 + 2 + 3 + 4 + 6 = 16,所以可以写成两个丰富数之和的最小数是24。通过数学分析,可以证明所有大于 28123 的整数可以写成两个丰富数之和。但是,即使已知不能表示为两个丰富数之和的最大数小于此上限,也无法通过分析进一步降低此上限。
找出所有不能写成两个丰富数之和的正整数之和。
我的代码的主要问题
- 错误答案
- 运行时间过长
我的代码
import java.util.ArrayList;
public class Problem23NonAbundantSums {
static ArrayList<Integer> abundantNumbers = new ArrayList<Integer>();
static ArrayList<Integer> sumOfAbundantNumbers = new ArrayList<Integer>();
static int max = 28123;
public static void main(String[] args) {
long start = System.currentTimeMillis();
getAbundantNumbers();
int temp = 0, sum = 0;
for (int i = 0; i < abundantNumbers.size(); i++) {
for (int j = i; j < abundantNumbers.size(); j++) {
temp = (abundantNumbers.get(i) + abundantNumbers.get(j));
if (temp < max) {
sumOfAbundantNumbers.add(temp);
}
}
}
for (int i = 1; i <= max; i++) {
if (sumOfAbundantNumbers.contains(i) == false) {
sum += i;
}
}
System.out.println(sum);
long stop = System.currentTimeMillis();
System.out.println((stop - start) + "ms");
}
public static boolean isAbundant(int x) {
int divisorSum = 0;
for (int i = 1; i < x; i++) {
if (x % i == 0) {
divisorSum += i;
}
}
if (divisorSum > x) {
return true;
}
return false;
}
public static void getAbundantNumbers() {
for (int i = 1; i < max; i++) {
if (isAbundant(i)) {
abundantNumbers.add(i);
}
}
}
}
编辑:我得到 4207994,这是错误的答案。运行需要 79081 毫秒,我希望它在 1 分钟内,因为它在 Project Euler 主页上说所有问题都可以在 1 分钟内解决。
编辑#2:我实际上发现了if条件中的问题
for (int i = 0; i < abundantNumbers.size(); i++) {
for (int j = i; j < abundantNumbers.size(); j++) {
temp = (abundantNumbers.get(i) + abundantNumbers.get(j));
if (temp < max) {
sumOfAbundantNumbers.add(temp);
}
}
}
temp < max 应该是temp <= max
有人对如何优化它有想法吗?提前致谢。
【问题讨论】:
-
你得到什么答案?您是否尝试过使用调试器?您希望代码运行多快(Big O-wise)?它现在的运行速度有多快?如果没有足够的上下文,很难回答一个问题。
-
我会确保它首先计算出正确的答案。如果它错了,需要多长时间都没关系。
-
解决方案需要时间,我认为这很正常,至少我的做到了。正如彼得所说,最好是尝试使用小数字,在启动更大数字的程序之前检查它是否有效。我在这里给你一个提示:我使用了一个列表倒出丰富的数字和一个所有数字 0
标签: java