2015-10-18 26 views
4

我正在嘗試使用遞歸來查找製作給定數量的最小硬幣數量。我有能夠列出所需硬幣最小數量的代碼,但我似乎無法找到打印出使用哪個硬幣來提供解決方案的方法。我搜索並找到了類似的例子,但我似乎無法正確地將其應用於此。打印哪些硬幣用於製作給定數量

這裏是我迄今:

import java.util.*; 

public class Coins{ 

    public static int findMinCoins(int[] currency, int amount) { 
     int i, j, min, tempSolution; 

     min = amount; 

     for (i = 0; i < currency.length; i++) { 
      if (currency[i] == amount) { 
       return 1; 
      } 
     } 

     for (j = 1; j <= (amount/2); j++) { 
      tempSolution = findMinCoins(currency, j) + findMinCoins(currency, amount - j); 
      if (tempSolution < min) { 
       min = tempSolution; 
      } 
     } 
     return min; 
    } 

    public static void main(String[] args) { 
     Scanner in = new Scanner(System.in); 
     int[] USA = 
     {1, 5, 10, 25, 50}; 
     System.out.println("Please enter an integer amount."); 
     int amount = in.nextInt(); 
     int minCoins = findMinCoins(USA, amount); 
     System.out.println("The minimum number of coins to make " + amount + " in United States currency is " + minCoins + "."); 
     System.out.println("The coins used were:"); 
     /*Print coins used to find minCoins.*/ 
     in.close(); 
    } 
} 

代碼運行至今的一個例子:

Please enter an integer amount. 
17 
The minimum number of coins to make 17 in United States currency is 4. 
The coins used were: 

如果有人可以給我如何做到這一點一些見解,它會非常感謝。

+0

有什麼可用的硬幣?另外,試着描述它應該如何工作 - 當前代碼對於某些輸入永遠運行(例如,44例如) – chenchuk

+0

關於質量的附註:請考慮源代碼中的命名。這很糟糕。首先,有一些公約;例如類名開始大寫。然後:一個名字應該說出它命名的是什麼。所以,數字是一個數字,並且重視一個價值......嗯?對於實際的問題,你可能想要開始在這裏和那裏使用printlns ...只是爲了打印中間結果;這可能會給你一個線索......在哪裏以及如何添加相關的打印輸出。 – GhostCat

+0

@chenchuk可用的硬幣可以是任何一組整數。對於我發佈的代碼,我只是使用{1,5,10,25,50}。至於結果,它打印出字符串「以美國貨幣制造17的硬幣的最小數目是4」。如果輸入17。我不確定如何在不使用動態編程的情況下以更高的值提高運行時間。 – Sigonious

回答

2

我認爲這應該完全符合您的要求。只需撥打public static int findMinCoins(arg1, arg2)它就會使用遞歸算法爲您輸出最小數量的硬幣和所有特定硬幣(它會顯示其出現次數)。

public static int findMinCoins(int[] currency, int amount) { 
    int min = findMinCoins(currency, amount, 0); 
    System.out.print("The coins used were: "); 
    return min; 
} 
private static int findMinCoins(int[] currency, int amount, int min){ 
    int number, value1, value2; 
    int min1 = min; 
    for(int i=currency.length-1; i>=0; i--) { 
     if (amount>=currency[i]){ 
      amount = amount - currency[i]; 
      System.out.print(currency[i] + " "); 
      min1 = findMinCoins(currency, amount, min1); 
      return ++min1; 
     } 
    } 
    return min1; 
} 
+0

如果貨幣數組的大小發生更改,這將不起作用。 – ESala

+0

如果我會用索引編寫這些ifs,我會感到嚴重的手腕疼痛。 –

+0

@Darkean更新!這個答案是OP的問題。 –

0

在這裏,你有一個測試,功能如下。請注意,未處理邊緣案例,例如空貨幣或負數。

假定貨幣數組已排序。如果不是,則用Arrays.sort(currency)進行分類。

public class FindMinimumCoinsTest { 

    @Test 
    public void test() throws Exception { 
     int[] USA = { 1, 5, 10, 25, 50 }; 
     assertEquals(2, findMinCoins(USA, 11)); 
     assertEquals(4, findMinCoins(USA, 8)); 
     assertEquals(4, findMinCoins(USA, 111)); 
     assertEquals(3, findMinCoins(USA, 27)); 
    } 

    public static int findMinCoins(int[] currency, int amount) { 
     int coins = 0; 
     int sum = 0; 
     int value, n; 

     for (int i = currency.length - 1; i >= 0; i--) { 
      value = currency[i]; 
      n = (amount - sum)/value; 
      if (n > 0) { 
       coins += n; 
       sum += n * value; 
      } 
     } 
     return coins; 
    } 
} 

而且,沒有必要使用此方法遞歸;)

+0

謝謝你的回答,但這個程序的一個要求是它使用遞歸來找到解決方案。我能夠找到一個動態編程解決方案,但似乎無法找出一種方法來打印最小硬幣和使用遞歸來找到最小硬幣。 – Sigonious

0

這裏是一個遞歸碼(工作,但需要一個修復...)。 的想法是通過,並與所有硬幣{1,5,10,25,50}和遞歸調用陣列從左至右(直到陣列的端部)

NOTES:

有一個小錯誤在輸出中

該數字以1個元素的數組而不是基元int的形式傳遞。 (這是爲了有一個引用類型通過所有的遞歸調用,以保持它的價值:

public class coins { 

    public static void main(String[] args) { 
     // arrays of coin types 
     int[] coinTypes = { 0, 1, 5, 10, 25, 50 }; 
     // arrays are references, so changing them 
     // inside the recursive function will 'really' change 
     int[] price = {11}; // sample input 
     tryBigger(price, coinTypes, 0); 
    } 

    // tries to see if higher coin is possible by passing array 
    // of coin types and recursively call until the end of array 
    public static void tryBigger(int[] price, int[] theCoins, int index) { 
     if (index < theCoins.length-1){ 
      // until last element 
      if (price[0] > theCoins[index]){ 
       tryBigger(price, theCoins, ++index); 
      } 
     } 
     // find amount of this coin 
     int thisCoin = price[0]/theCoins[index]; 
     // remove the amount already got before 
     price[0] = price[0] - thisCoin*theCoins[index]; 
     System.out.println(thisCoin + " coins of " + theCoins[index]); 
     return; 

    } 
} 
+0

這種輸出格式是我正在尋找的,但我相信這使用了「作弊」方法來解決它。例如,如果您使用貨幣組{1,2,3,5,7,11,13}並將價格更改爲22,則會得到13,7和2的硬幣結果,而不是兩個11硬幣。謝謝你的回答。 – Sigonious

+0

這是算法中的一個重大差異。我的算法嘗試擁有最大可能的硬幣,您的硬幣數量最少(任何類型) - 是您的意思? – chenchuk

0

在您提供的代碼,無論是數量1min由遞歸函數返回用這種方法保持一致,單向你可以獲得硬幣列表是通過改變返回變量來包括硬幣和計數

下面是一個總體思想的例子;因爲我不知道Java編程,所以我將把實現留給你。

if (currency[i] == amount){ 
    return [1,i]; 

... 

temp1 = findMinCoins(currency,j); 
temp2 = findMinCoins(currency,amount - j); 

if(temp1[0] + temp2[0] < min[0]){ 
    min = [temp1[0] + temp2[0]] concatenated with temp1[1..] and temp2[1..]