0

在尝试编写一个简单的括号平衡函数时,我了解到我不知道 scala 如何评估 if 语句。

def balance(chars: List[Char]): Boolean = {
  def loop(chars: List[Char], opened: Int): Boolean = {
    println(opened)
    println(chars.head)
    if (opened < 0) return false
    if (chars.isEmpty && opened == 0) return true
    if (chars.isEmpty && opened > 0) return false
    if (!chars.isEmpty && chars.head.toString == "(") loop(chars.tail, opened+1)
    if (!chars.isEmpty && chars.head.toString == ")") loop(chars.tail, opened-1)
    else loop(chars.tail, opened)
  }
loop(chars, 0)
}

当我运行它时,到第三次迭代时,它将 println(opened) 并声明打开 = -1。我以为 (opened < 0) ----> (-1 < 0) -----> true,所以我会返回 false。事实并非如此——为什么?

4

1 回答 1

2

Scalaif按照声明的顺序计算表达式。这个算法的问题是它假设最后一个else表达式只有在没有其他条件为真时才会被评估if,但是输入'(X))'你将创建两个递归树:一个用于条件!chars.isEmpty && chars.head.toString == "(",另一个用于else loop(chars.tail, opened). 这会产生一种印象,即打开 =-1 时递归并未结束,但实际上您看到的是“else”递归树。

解决方案?您只是缺少一个else

if (!chars.isEmpty && chars.head.toString == "(") loop(chars.tail, opened+1) **else**

(注意:此代码可能可以使用match...case语句进行改进。这将防止以前的else问题发生。此外,您可以将字符与字符进行比较。无需将它们转换为字符串:chars.head.toString == "("=> chars.head == '('

* 编辑 * 在您发表评论后,您可以在列表结构中使用模式匹配:

def loop(chars: List[Char], opened: Int): Boolean = {
    if (opened < 0) return false else 
    chars match {
    case Nil => opened == 0
    case '('::tail => loop(tail, opened + 1)
    case ')'::tail => loop(tail, opened -1)
    case x::tail => loop(tail, opened)
}

我希望这有帮助。

于 2013-09-26T22:43:22.043 回答