【问题标题】:Trying to understand parenthesis balancing recursion in Scala试图理解 Scala 中的括号平衡递归
【发布时间】:2017-07-02 16:28:40
【问题描述】:

我是 Scala 和函数式编程的新手。免责声明:是的,我正在 Coursera 上学习 Scala 课程,是的,这是作业的一部分。我在这里的唯一目标是获得一些帮助以了解此解决方案的工作原理,以便开发我自己的解决方案并熟悉函数式编程。

我坚持使用递归算法的这种实现来检查括号平衡。我根本不明白:

  1. 函数的结构
  2. 如何计算布尔表达式
def balance(chars: List[Char]): Boolean = {
  def balanced(chars: List[Char], open: Int): Boolean = {
    if (chars.isEmpty) open == 0
    else
    if (chars.head == '(') balanced(chars.tail,open+1)
    else
    if (chars.head == ')') open>0 && balanced(chars.tail,open-1)
    else balanced(chars.tail,open)
  }
  balanced(chars,0)
}

我的第一个疑问如下。内部函数立即开始计算布尔表达式

if (chars.isEmpty) open == 0

我的理解(可能是错误的)是这里将评估两个表达式:chars.isEmptyopen==0。 但是,参数open 似乎还没有在任何地方定义。那么为什么我没有收到错误消息? 其次,我根本听不懂:

if (chars.head == '(') balanced(chars.tail,open+1)

balanced(chars.tail,open+1) 将在哪里进行评估以及如何评估?

假设我想检查"(" 是否有平衡括号。

if (chars.isEmpty) open == 0

会返回False,然后

if (chars.head == '(') balanced(chars.tail,open+1)

第一个表达式将为 TRUE,但第二个表达式呢? "(" 没有尾巴,我也看不出open+1 是如何工作的,因为整数open 尚未在任何地方定义。我很困惑。

【问题讨论】:

  • 你说open没有定义是什么意思?它是函数的参数之一。
  • 是,但没有为其分配任何值。如果 open 到目前为止没有任何价值,我怎么知道 open == 0?
  • 按照同样的逻辑,您可能会争辩说您不知道chars 的值是什么。在调用函数之前,不会评估函数的主体。一旦发生这种情况,你就知道争论是什么了。

标签: scala recursion


【解决方案1】:

您误解了其中一项基本内容 - 函数定义。让我们跳过程序中最初不重要的部分:

def balance(chars: List[Char]): Boolean = {
  def balanced(chars: List[Char], open: Int): Boolean = { /* ... */ }
  balanced(chars,0)
}

注意balance 函数的第一行只是一个函数定义——它是一个局部函数。一旦控制流到达balanced(chars, 0) 行,它将调用此函数 - 因此open 变量将被初始化为0

希望这能解决您的“未初始化变量”问题。如果您还有任何问题,请发表评论,我会尽力为您提供进一步的帮助。

【讨论】:

  • 谢谢,这有助于解决我的第一个重要疑问。我仍然不明白如何评估 if (chars.head == '(') balanced(chars.tail,open+1)。如何将balanced(chars.tail,open+1) 评估为布尔值?如果我有,如前所述,“(”,第一个表达式将给出 True,但我不知道如何减少第二个。非常感谢您的帮助
  • @Kauber 嗯,不知道你在那里缺少什么——balanced(chars.tail, open + 1) 只是一个函数调用——一个返回布尔值的函数。它的工作原理与任何其他编程语言完全相同。
  • 我想我知道了,我明白了什么是函数调用,但正如原帖中所说,我对函数的结构感到非常困惑。再次感谢您
  • @Kauber 另请注意,如果没有 else 部分,if (chars.head == '(') balanced(chars.tail,open+1) 本身不会被评估;这就像问2 + 是如何评估的。
猜你喜欢
  • 1970-01-01
  • 2013-11-18
  • 1970-01-01
  • 2012-09-15
  • 2019-10-22
  • 2015-10-18
  • 2011-02-12
  • 1970-01-01
  • 2018-06-10
相关资源
最近更新 更多