2013-05-10 79 views
2

我正在嘗試Java硬幣更改問題以枚舉所有可能的更改集。Java遞歸硬幣更改嘗試

我的邏輯如下這樣:

while n >= denom m { 
array[]+= denom m 
n-= denom m 
} 
list.add[array[]] 

return coinChanger(++denom) 

我的代碼:

public List<Integer> makeChange(int change) { 

    int[] denominations; 
    denominations = new int[]{1, 5, 10, 25}; 

    return changeMaker(change, denominations, 0); 
} 

public List<Integer> changeMaker(int change, int[] denominations, int index) { 
    List<Integer> resultsList = new ArrayList<Integer>(); 
    int[] resultDenom; 
    resultDenom = new int[4]; 

    if (change <= 1) { 
     return resultsList; 
    } 

    while (change >= denominations[index]) { 
     resultDenom[index] += denominations[index]; 
     System.out.println("ResultsDenom: " + resultDenom[index]); 
     change -= denominations[index]; 
    } 
    resultsList.add(resultDenom[index]); 

    for (int val : resultDenom) { 
     System.out.println(val); 
    } 


    if (change > denominations[index]) {  
     return changeMaker(change-=denominations[index], denominations, ++index);  

    } 
    return resultsList; 
} 

該輸出僅1組的所有枚舉:

OUTPUT:

27 
0 
0 
0 
RESULT CHANGE PERMUTATIONS LIST: [27] 

問題:

我竭力要弄清楚如何移動到下一面額,一旦其中一人完成...我知道你應該移到面額數組中的下一個索引...但是那只是增加了下一枚硬幣......我如何使它增加下一枚最大的硬幣,然後遞歸地下降到下一枚硬幣......一直穿過所有4枚硬幣?

謝謝!

* 編輯 **

public List<Integer> makeChange(int change) { 

    int[] denominations; 
    denominations = new int[]{25, 10, 5, 1}; 

    return changeMaker(change, denominations, 0); 
} 

public List<Integer> changeMaker(int change, int[] denominations, int index) { 
    List<Integer> resultsList = new ArrayList<Integer>(); 
    int[] resultDenom; 
    resultDenom = new int[4]; 

    if (change <= 1) { 
     return resultsList; 
    } 

    if (index > 3) { 
     return resultsList; 
    } 
    //if 27 >= 25 
    if (change >= denominations[index]) { 

     //[+25, 0, 0, 0] 
     resultDenom[index] += denominations[index]; 

     //{ LIST } <--- [25, 0, 0, 0] 
       //List now contains { [25, 0, 0, 0], }, still need all other permutations 
     resultsList.add(resultDenom[index]); 

     //27 - 25, 
     return changeMaker(change-=denominations[index], denominations, ++index);  

    } 
    return resultsList; 
} 

所需的輸出:列出清單...... 27美分:

LIST{ [1, 0, 0, 2], [0, 2, 1, 2], [0, 1, 3, 2]... etc}

+0

是你的整個輸出? System.out.println(「ResultsDenom:」+ resultDenom [index]);'? – noMAD 2013-05-10 19:41:41

+0

如果你的輸入是'27',並且你沒有任何改變就使用了上面的代碼,那麼輸出就不能成爲你的輸入。 – noMAD 2013-05-10 19:43:22

+0

http://stackoverflow.com/search?q=coin+change ... – 2013-05-10 19:43:23

回答

-1

你的代碼似乎爲一個有點令人費解您正在嘗試解決的問題

嘗試實施這一僞碼

getChange(int totalCents) 
    { 
     if (totalCents > 25) 
     { 
     print "25"; 
     getChange(totalCents - 25); 
     } 
     else (totalCents > 10) 
     { 
     // same for 10 
     } 
     else (totalCents > 5) 
     { 
     // same for 5 
     } 
     else 
     { 
     // print out number left as pennies 
     } 
    } 

你可以很容易的更換,如果語句與數組索引硬編碼值和一個for循環,並與印刷但是你要錄製的值。我希望有所幫助。

+0

這是如何完成列舉所有可能的集? – Growler 2013-05-10 19:47:48

+0

更改'if()else'條件的順序xD現在你知道蠻力的方式了,看看你怎樣才能更優雅地做到這一點 – noMAD 2013-05-10 19:50:39

3

簡單的辦法是遞歸到每一步兩個變體(如果你還沒有完成):

  1. 繼續使用當前的硬幣:將它添加到列表和遞歸。
  2. 切換到下一個硬幣:增加硬幣pos和遞歸。

應該是這樣的:

public class Coins { 
    static final int[] DENOMINATIONS = {25, 10, 5, 1}; 

    public static void change(int amount) { 
    change(amount, new ArrayList<Integer>(), 0); 
    } 

    private static void change(int remaining, List<Integer> coins, int pos) { 
    if (remaining == 0) { 
     System.out.println(coins); 
    } else { 
     if (remaining >= DENOMINATIONS[pos]) { 
     coins.add(DENOMINATIONS[pos]); 
     change(remaining - DENOMINATIONS[pos], coins, pos); 
     coins.remove(coins.size() - 1); 
     } 
     if (pos + 1 < DENOMINATIONS.length) { 
     change(remaining, coins, pos + 1); 
     } 
    } 
    } 
} 

如果你想收集名單,你需要做,其中一個硬幣從調用返回後增加(而不是刪除它的列表的副本)。

+0

啊,我很接近。我正在'changeMaker'中創建一個新列表,每次調用我將當前面額添加到...然後我將這個resultDenom數組添加到resultsList ...順便說一句,不是放'coins.remove(硬幣。 size() - 1);'在遞歸調用'change(剩餘 - DENOMINATIONS [pos],coins,pos)後''使它無法訪問?另外,我想我要把列表中的總硬幣列在列表清單中,因此對於52美分它將是:'LIST [{2,0,0,2},{1,2,1,2 },{0,5,0,2}等等],而不是像你所做的那樣在新列表中加入硬幣,'[25,25,1,1],[25,10,10,5 ,2]',等等... – Growler 2013-05-13 14:45:33

+0

哎呀,它不會無法訪問...它是我的,因爲我返回一個列表'return changeMaker(change- = denominations [index],coinsList,index);'after我將當前的面額添加到coinsList ...你能解釋爲什麼你要做'coins.remove(coins.size() - 1);',我不知道爲什麼這是必要的刪除 – Growler 2013-05-13 15:00:02

+0

那是因爲我在第二次遞歸調用中重用相同的列表。如果我不這樣做,那麼不加入硬幣即可直接進入下一個面額的情況。另一種方法是在第一次遞歸調用之前複製列表。你也可以爲其中一個情況做一個循環(並且在循環內進行遞歸),但是對於我來說,一個純粹的遞歸版本似乎更簡單。 – 2013-05-13 16:15:34