【问题标题】:Parenthesis Balancing Algorithm括号平衡算法
【发布时间】:2016-09-30 22:20:21
【问题描述】:

我正在使用 scala 中的一个小程序来检查某些表达式是否正确地形成了关于括号的打开和关闭。这是here 的问题,但我自己的程序。

def balance(chars: List[Char]): Boolean = {
  def balanced(chars: List[Char], opened: Int, closed: Int): Boolean = {
   if (chars.isEmpty && opened == closed) true
   else if (opened < closed) false
   else {
    if (chars.head == '(') balanced(chars.tail, opened + 1, closed)
    if (chars.head == ')') balanced(chars.tail, opened, closed + 1)
    else balanced(chars.tail, opened, closed)
   }
 }
  balanced(chars, 0, 0)

}

println(balance("Just (some (random) sentence).\n(That doesn't work)".toList))

问题在于,例如,它不适用于此示例。我跟踪了程序,显然当我们从递归调用返回时出现了问题,但我无法弄清楚错误是什么。

【问题讨论】:

  • “不起作用”到底是什么意思?你有输出吗?
  • @Zermingore 是的,对于 println 语句,它应该返回 true,但实际上返回 false
  • 你也可以考虑使用组合解析器(例如 atto)来解决这类问题,尽管这有点矫枉过正。
  • @Reactormonk,有点矫枉过正,是的。这是 Coursera 课程练习...
  • 如果这是 Scala 中的函数式编程原则 第一周的作业(并且测试字符串强烈表明它是),这违反了 Coursera 的荣誉准则.

标签: scala functional-programming


【解决方案1】:

else {
    if (chars.head == '(') balanced(chars.tail, opened + 1, closed)
    if (chars.head == ')') balanced(chars.tail, opened, closed + 1)
    else balanced(chars.tail, opened, closed)
}

当您想将两个独立的if 表达式视为单个案例表达式时,您有两个独立的表达式。如果chars.head == '('true,则进行递归调用,但忽略结果并评估第二个if。这将导致采用else 分支,该分支有效地忽略了在第一个表达式中找到的(。您可以使用match,例如

chars match {
  case Nil => opened == closed
  case '('::cs => balanced(cs, opened + 1, closed)
  case ')'::cs => balanced(cs, opened, closed + 1)
  case _::cs => balanced(cs, opened, closed)
}

【讨论】:

  • 就是这个!也可以用 else if 代替第二个 if 来解决。谢谢
【解决方案2】:

你可以试试下面的代码,可能是它在上面的例子中对你有用,如果你有“sss)fff(”也有问题,所以它在逻辑上会出错

def balance(chars: List[Char]): Boolean = {
    def balrec(chars: List[Char], accr: Int, accl: Int): Boolean = {
      chars match {
        case head :: tail =>
          if (head.equals('(')) balrec(tail, accr + 1, accl)
          else if (head.equals(')') && (accr > accl || accr == 0)) balrec(tail, accr, accl + 1)
          else balrec(tail, accr, accl)
        case Nil => if (accr == accl) true else false
      }
    }

    balrec(chars, 0, 0)
  }

【讨论】:

  • 提供完全不同的代码没有什么意义,即使它有效。 OP 提供了一个带有工作示例的问题的链接。这是一个关于他们的代码出了什么问题的问题,而不是要求其他解决方案。
  • @TheArchetypalPaul 它不是另一个解决方案,它与 lee 回答中提到的相同,它不在同一个匹配案例中,所以我把它放在相同的位置并给出整体解决方案
  • 不,完全不同。参数名称变了,case 语句组织不好,测试顺序不同。
  • @TheArchetypalPaul 抱歉,但是当我尝试解决某些问题时,我无法复制变量名称,我只是在我的 REPL 上尝试它,然后我把名字放在我的脑海中
  • 它“相同”只是因为它是解决问题的递归函数。在几乎所有其他方面,它都是不同的。它还认为 ")()" 是平衡的,所以它甚至不正确。
猜你喜欢
  • 1970-01-01
  • 2013-11-18
  • 2016-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-05
  • 2016-11-27
  • 2015-05-01
相关资源
最近更新 更多