2016-09-10 39 views
0

我已經潛伏了多年,但今天我有一個關於我的代碼的問題。我目前正在嘗試創建一個collat​​z程序,它將某個數字的步數放在一個數組中,但同時會爲每個經過的數字設置步數。這裏是我的代碼: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; 
     } 
    } 
    } 
} 

這裏是在考拉茲猜想一個偉大的視頻:Numberphile

因此,這裏是被拋出(減少)的錯誤,但我不明白,因爲我沒有在任何地方靠近任何int或短的界限:

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

格式化您的代碼,然後調試代碼。 – SMA

+0

'StackOverflowError'與'int'或'short'的邊界無關。你是否熟悉堆棧的概念? –

+0

@Marko Topolnik我以爲我做過,但顯然不是!如果您不願意,我將不勝感激。 – Erik

回答

0

正如在繼續1的視頻片段中所述,將會以無限循環結束。 請嘗試以下操作。

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

countCollatz只需計算所需步驟 - 實際達到1。儘管直到進一步證明,可能會出現更高數量的循環。

我已經使用了Java 8 lambda表達式IntFunction f,因爲重複計算更爲自然,一次填充數組,一次填充太大的數字。