我已经潜伏了好几年,但今天我对我的代码有疑问。我目前正在尝试创建一个collatz程序,它将某个数字的步数放在一个数组中,但同时为它所经过的每个数字设置步数。这是我的代码:
public class GenerousRecursion {
public static short steps;
public static int length;
public static short[] array = new short[101];
public static void main(String[] args) {
length = 100;
for (int count = 2; count < length + 1; count++){
steps = 0;
System.out.println(count + ": " + findCollatz(count));
}
}
public static short findCollatz(int number) {
if (number < length){
if (array[number] > 0) {
steps = array[number]++; return steps;
}
else if(number % 2 == 0) {
array[number] = findCollatz(number / 2);
steps ++;
return steps;
}
else {
array[number] = findCollatz(3 * number + 1);
steps ++;
return steps;
}
}
else {
if(number % 2 == 0) {
findCollatz(number / 2);
steps ++;
return steps;
}
else {
findCollatz(3 * number + 1);
steps ++;
return steps;
}
}
}
}
这是关于Collatz猜想的精彩视频:Numberphile
所以这里是错误被抛出(减少),但我不明白,因为我不是任何接近任何int或short的界限:
Exception in thread "main" java.lang.StackOverflowError
at GenerousRecursion.findCollatz(GenerousRecursion.java:22)
at GenerousRecursion.findCollatz(GenerousRecursion.java:33)
at GenerousRecursion.findCollatz(GenerousRecursion.java:27)
我刚刚列出了前三行,因为这三行同样会产生数百行错误。
问题是什么,我该如何解决?非常感谢!
编辑:当我运行调试器时,我的程序会在数组被引用时不断抛出异常。
答案 0 :(得分:0)
正如视频剪辑中所述,继续1将以无限循环结束。 请尝试以下方法。
functions $_comps[cd]
static int[] collatzCounts = new int[100];
static final int NO_COUNT = -1;
static {
Arrays.fill(collatzCounts, NO_COUNT);
collatzCounts{1] = 0; // Define collatz(1) = 0 (1, 4, 2, 1, ...)
}
public static void main(String[] args) {
for (int n = 2; n < 120; n++) {
int steps = countCollatz(n);
System.out.println(n + ": " + steps);
}
}
public static int countCollatz(int n) {
IntFunction f = k ->
k % 2 == 0
? 1 + countCollatz(k / 2)
: 1 + countCollatz(3 * k + 1);
//: 2 + countCollatz((3 * k + 1) / 2);
//if (n == 1) {
// return 0;
//}
if (n < collatzCounts.length) {
if (collatzCounts[n] == NO_COUNT) {
collatzCounts[n] = f.apply(n);
}
return collatzCounts[n];
} else {
return f.apply(n);
}
}
只需计算所需的步骤 - 实际达到1。虽然进一步证明可能存在更高数字的循环。
我使用了Java 8 lambda表达式,即IntFunction f,因为重复计算更自然,一次填充数组,一次是因为数字太大。