在scala中使用可变堆栈的平衡括号算法

时间:2016-07-24 22:48:30

标签: scala

我最近接受了斯卡拉的采访。问题是要解决给定字符串是否具有平衡括号。

例如,“(({[]}))”是平衡的,其中“(({(}})”“不是。

我提供了以下解决方案 -

    object BalancedBrackets {

      def main(a: Array[String]): Unit = {
        println(balancedBrackets("((()))"))
      }


      def balancedBrackets(s: String): Boolean = {

        import scala.collection.mutable.Stack
        import scala.util.control.Breaks._
        var brackets = Stack[Char]()
        try {
          for (c <- s) {
            println(c)
            c match {
              case '(' | '{' | '[' => brackets.push(c)
              case ')' => var c1 = brackets.pop; if (c1 != '(') {
                break
              }
              case '}' => var c1 = brackets.pop; if (c1 != '{') {
                break
              }
              case ']' => var c1 = brackets.pop; if (c1 != '[') {
                break
              }
            }
          }

          if (brackets.size == 0) true else false
        } catch {
          case ex: Exception => println("Exception"); ex.printStackTrace(); false
        }
      }

    }

但是面试官要求使用不可变堆栈而不是mutable,因为mutable不是线程安全的,并且它在多线程环境中无法正常工作。

我不确定如何使用不可变堆栈在scala中实现相同的算法。任何人都可以帮助我。

3 个答案:

答案 0 :(得分:2)

在您的解决方案堆栈中只包含括号。如果文本中的下一个括号与堆栈中的顶部括号匹配,则它们将被删除 当结果堆栈为空时,托架被认为是平衡的。

foldLeft的主要优点是它在for循环上进行抽象。循环中剩下的是从先前结果​​和当前值到下一个结果(Stack[Char], Char) => Stack[Char]的函数。这种签名鼓励每次迭代返回新堆栈。

def balanced(text: String): Boolean = {
  val parenthesis = Map('}' -> '{', ')' -> '(', ']' -> '[', '>' -> '<')

  val isParenthesis: (Char) => Boolean = c => parenthesis exists { case (closed, opened) => closed == c || opened == c }
  val isClosing: (Char) => Boolean = parenthesis.contains
  val openingFor: (Char) => Option[Char] = parenthesis.get

  text.toCharArray
    .filter(isParenthesis)
    .foldLeft(Stack[Char]())((stack, p) => {
      if (isClosing(p) && openingFor(p) == stack.headOption) stack.pop
      else stack.push(p)
    }).isEmpty
}

答案 1 :(得分:1)

我回答了你的问题,我想出了这个解决方案:

enum classes

正如你所看到的,没有状态突变。

如果你想使用Scala,你必须在函数式编程上多搜索一下。

我建议您阅读“Scala中的函数编程” 而“Scala编程”都是很棒的书!我将从“Scala中的函数编程”开始,因为它将向您介绍这种新的编程范例。

答案 2 :(得分:1)

这是另一种使用递归函数的解决方案,与foldLeft不同,它支持早期中断,因此更有效。包括一些测试用例。我也使用链表而不是堆栈,它是不可变的,并且具有与不可变堆栈相同的效率。

ROW_NUMBER