3

我正在尝试使用 java 硬币找零问题来枚举为 n 提供的所有可能的找零集。

我的逻辑如下:

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

这仅输出一组所有枚举:

输出:

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}

4

2 回答 2

6

最简单的解决方案是在每一步递归成两个变体(如果你还没有完成):

  1. 继续使用当前硬币:将其添加到列表中并递归。
  2. 切换到下一个硬币:增加硬币位置并递归。

应该是这样的:

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

如果要收集列表,则需要复制添加硬币的列表(而不是在调用返回后将其删除)。

于 2013-05-10T23:18:10.850 回答
-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
      }
  }

您可以轻松地将 if 语句替换为带有数组索引和 for 循环的硬编码值,并使用您希望记录的值进行打印。我希望这会有所帮助。

于 2013-05-10T19:44:29.947 回答