Collat​​z猜想递归错误

时间:2016-09-10 13:44:37

标签: java arrays stack-overflow collatz

我已经潜伏了好几年,但今天我对我的代码有疑问。我目前正在尝试创建一个collat​​z程序,它将某个数字的步数放在一个数组中,但同时为它所经过的每个数字设置步数。这是我的代码:

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

这是关于Collat​​z猜想的精彩视频: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)

我刚刚列出了前三行,因为这三行同样会产生数百行错误。

问题是什么,我该如何解决?非常感谢!

编辑:当我运行调试器时,我的程序会在数组被引用时不断抛出异常。

1 个答案:

答案 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,因为重复计算更自然,一次填充数组,一次是因为数字太大。