【问题标题】:Scala: IndexOutOfBoundsException: -1斯卡拉:IndexOutOfBoundsException:-1
【发布时间】:2017-06-19 15:48:06
【问题描述】:

我一步一步地查看了这个函数,在我看来,它应该避免调用sortedCoins(0-1),只使用sortedCoins(0) 并在y == -1 时终止,但不知何故它没有。为什么?

def countChange(amount: Int, coins: List[Int]): Int = { 
    var x = coins.length 
    var y = x
    val sortedCoins = coins.sortWith(_ < _) 
    def cc(amount: Int, x: Int): Int = {
        y -= 1
        if (amount == 0) 1 
        else if (y == 0) cc(amount - x, sortedCoins(y))
        else if (amount < 0 || y == -1) 0  
        else cc(amount, sortedCoins(y - 1)) + cc(amount - x, sortedCoins(y))    
    }

    cc(amount, x) 
}

【问题讨论】:

  • 我建议学习如何使用调试器逐行执行程序。这对您非常有用(对于这个和未来的问题)。令人惊讶的是,提问者可以通过这种方式更轻松地为自己解决多少问题
  • 在另一张纸条上,当我看到coins: List[Int] 它可能应该是coins: List[Coin] 时,它让我很生气。至少你应该使用一个值类,但实际上你应该使用 ADT(代数数据类型)
  • 这是作业题吗?好像我在 Coursera 课程中看到过这个......
  • 是的,countChange函数的这种定义签名有一个问题需要解决。已经与这个谜题战斗了 10 个小时

标签: scala list exception indexoutofboundsexception


【解决方案1】:

您需要重新考虑编写此算法的方式。您在递归函数中看到 y 变量是“全局”范围,当您执行函数时,它将转到

cc(amount, sortedCoins(y - 1)) + cc(amount - x, sortedCoins(y))

多次,它将执行等式的第一边,并且每次都会递减y。然后,y 将变为 0,而您的

else if (y == 0)  cc(amount - x, sortedCoins(y))

line 将被执行,接下来因为 y=-1 你的

else if (amount < 0 || y < 0) 0 

行将被执行。这里我们来个异常,因为这一行返回0,递归执行last else方程的第二部分,即

cc(amount - x, sortedCoins(y))

,现在 y=-1,这就是你有这个例外的原因。我希望这是可以理解的。

【讨论】:

  • else if (amount &lt; 0 || y == -1) 0 如果返回 0,那么函数应该终止,因为函数返回 Int。为什么它会继续并检查下一个“else”?
  • 它不检查下一个 else,你递归调用 times cc 函数。当等式左侧返回 0 时,调用等式右侧,参数如 (amount - x, sortedCoins(y)) 以及为什么存在 -1。 sortedCoins 是 List 所以你有 indexOutOfBound
猜你喜欢
  • 2011-09-16
  • 2016-01-31
  • 2017-10-23
  • 1970-01-01
  • 2017-01-19
  • 1970-01-01
  • 2021-06-09
  • 2021-11-06
  • 2011-12-29
相关资源
最近更新 更多