使用递归的scala中的硬币更改算法

Mua*_*via 15 scala scala-2.9

我试图使用递归编程Scala中的硬币更改问题.我写的代码如下.

def countChange(money: Int, coins: List[Int]): Int = {
  def ways(change: List[Int], size: Int, capacity: Int): Int = {
    if(capacity == 0) 1
    if((capacity < 0) || (size <= 0)) 0

    //println and readLine to check and control each recursive call.

    println("calling ways(",change, change.length-1, capacity,") + ways(",change,   change.length, capacity - change(change.length - 1),")")
    readLine()
    //

    ways(change, change.length-1, capacity) + ways(change, change.length, capacity - change(change.length - 1))
  }
  ways(coins, coins.length, money)
}
Run Code Online (Sandbox Code Playgroud)

在运行代码时,它不会终止并继续调用第一个递归调用.我哪里错了?

rke*_*nmi 88

很好,很简单

def countChange(money: Int, coins: List[Int]): Int = {
  if(money == 0)
    1
  else if(money > 0 && !coins.isEmpty)
    countChange(money - coins.head, coins) + countChange(money, coins.tail)
  else
    0
}
Run Code Online (Sandbox Code Playgroud)

  • 这里的想法是用尽我们的*硬币*并从当前的*金额*中减去它.最终,金额将是0,一些负数(意味着这种硬币组合失败),或一些正数(意味着我们仍然可以用我们现有的硬币减去更多).`countChange(money - coins.head,coins)`将耗尽从钱中减去第一枚硬币的所有组合,而`countChange(money,coins.tail)`仅使用所有其他硬币耗尽所有组合.它们被加在一起,因为+与逻辑OR运算符同义. (7认同)
  • 你能为这个解决方案提供一些直觉吗? (4认同)
  • 解决方案很好.关于基本情况的一个问题:如果最初的钱是0怎么办?是不是有0种方式来改变0钱? (3认同)
  • 想象一下,您面前有一些硬币,然后要求您使用一大袋硬币来匹配它。如果您面前有一分钱,那么只有一种方法可以匹配它;用袋子里的一分钱 接下来,如果面前没有硬币怎么办?同样,只有一种方式可以代表这一点。不要从包里拿出任何硬币。现在最后,如果您有负数钱怎么办?好吧,你不能真正地在身体上表现出来。因此,有0种产生此输出的方法;在这种情况下,硬币袋是完全不相关的。 (3认同)
  • @rileyss 你可以通过展示 0 个硬币来代表 0 个钱。请记住,问题是“给定某种面额的硬币,我们可以用多少种方式来表示货币”。因此,使用零硬币仍然被认为是一种独特的方式。 (3认同)

小智 19

这是我的实现:我测试了它,它工作正常

def countChange(money: Int, coins: List[Int]): Int = {

    def count(capacity: Int, changes: List[Int]): Int = {
                if(capacity == 0) 
                  1
                else if(capacity < 0) 
                  0
                else if(changes.isEmpty && capacity>=1 )
                  0
                else
                        count(capacity, changes.tail) + count(capacity - changes.head, changes)
    }

    count(money, coins.sortWith(_.compareTo(_) < 0))
}
Run Code Online (Sandbox Code Playgroud)

  • 真的需要排序吗? (7认同)

Rex*_*err 8

简单地说明一个值并不能使Scala返回它; 你需要一个明确的回报,或者它必须是最后一个项目.从而:

if (capacity == 0) return 1
Run Code Online (Sandbox Code Playgroud)

要么

if (capacity == 0) 1
else if (...)
else { ... }
Run Code Online (Sandbox Code Playgroud)

  • @ user1050258 - 嗯,这不是唯一的问题 - 你也在各个地方使用`change.length-1`而不是`size-1`.您不在解决方案中更新`change`本身!(提示:如果你_did_更新`change`,那么你就可以避免这个bug并且不需要`size`参数....) (2认同)

Car*_*das 8

只是另一个解决方

def countChange(amount: Int, coins: List[Int]): Int = coins match {
  case _ if amount == 0 => 1
  case h :: t if amount > 0 => countChange(amount - h, h :: t) + countChange(amount, t)
  case _ => 0
}
Run Code Online (Sandbox Code Playgroud)