2016-05-29 23 views
0

我試圖使用遞歸實現硬幣更改問題。我寫了下面的代碼,並且面臨着靜態類變量的問題。 'answer'是一個類變量,我試圖在循環中添加返回值。這在while循環內正常工作,但while循環結束後,答案被重置爲0;Java遞歸類變量值重置爲0

while (i * currentCoin <= sum) { 
    System.out.println("inside while; answer is " + answer); 
      answer = answer 
      + findCombinations(
        sum - i * currentCoin, 
        new ArrayList<Integer>(denominations.subList(1, 
          denominations.size()))); 
    i++; 

} 

以下是我寫的所有代碼。你可以複製並運行它來檢查。

import java.util.ArrayList; 
    import java.util.Collections; 

    public class CoinChangeHashMap { 
static int answer = 0; 

public static void main(String[] args) { 

    int[] array = new int[] { 7, 3, 2 }; 
    ArrayList<Integer> input = new ArrayList<Integer>(); 
    getList(array, input); 
    findCombinations(12, input); 
    System.out.println(answer); 
} 

private static void getList(int[] array, ArrayList<Integer> input) { 

    for (int i : array) { 
     input.add(i); 
    } 

} 

public static int findCombinations(int sum, ArrayList<Integer> denominations) { 

    if (denominations.size() == 1) { 
     if (sum % denominations.get(0) == 0) { 
      return 1; 
     } 
     return 0; 

    } 
    int i = 0; 
    int currentCoin = denominations.get(0); 

    while (i * currentCoin <= sum) { 
     System.out.println("inside while; answer is " + answer); 

     answer = answer 
       + findCombinations(
         sum - i * currentCoin, 
         new ArrayList<Integer>(denominations.subList(1, 
           denominations.size()))); 
     i++; 

    } 
    return 0; 
}} 

**我得到的輸出爲0,但預期輸出爲4。在調試,我得到的輸出**

inside while; answer is 0 
inside while; answer is 0 
inside while; answer is 1 
inside while; answer is 1 
inside while; answer is 2 
inside while; answer is 2 
inside while; answer is 0 
inside while; answer is 0 
inside while; answer is 0 
0 

任何幫助表示讚賞。

+0

嘗試在遞歸調用 –

+0

未調試之後打印答案值,即'System.out.println()',調試實際上需要使用步調試器逐步執行代碼一條指令,而不僅僅是把東西打印出來。 –

+0

@JarrodRoberson,打印語句是一種久經考驗的真正的調試方法。此外,插入代碼中的print語句有助於向* us *展示問題。問題是關於爲什麼靜態變量的值被重置。 OP可能通過在調試器中運行代碼發現了自己的答案,但這並不是一個愚蠢的舉動。它甚至沒有表明缺乏研究。 –

回答

0

該問題與您的奇怪代碼結構有關,您通過修改靜態變量answer,有時通過方法的返回值來傳遞遞歸調用的結果。

如果您更仔細地分析了問題,您會發現它不是從循環中退出,而是部分結果丟失,而是從方法返回後的一段時間。因此,仔細考慮更新應答方式:

answer = answer + findCombinations(/* ... */); 

在你遞歸的最頂層,answer最初0。當Java評估上述表達式時,首先評估左操作數,然後評估右操作數,然後將它們相加。也就是說,它評估answer,得到結果0,之前它執行遞歸調用。 answer的值可能會在遞歸調用過程中更新,但這些更改來得太遲。只有遞歸的最底層才返回一個不等於零的值,所以如果遞歸調用本身遞歸至少一個更深的層次,那麼它將返回零。在這種情況下,總和計算爲0 + 0,並分配給answer,破壞所執行方法的任何更新。

您可以通過交換總和中操作數的順序來解決問題,但是完全擺脫靜態變量會更好,也不會太難。在方法中使用局部變量來累積結果,並且在所有情況下通過方法的返回值將總數傳回給調用者。