我是scala的新手,我正在尝试通过编写一个简单的程序来检查是否给定一个字符串,每个开放的paranthesis都有自己的闭括号。 例如,对于字符串“{{ssss {{}}}}}”,答案应该是错误的。 我正在使用的代码如下:
package recfun
import common._
import scala.collection.mutable.Stack
object Main{
def main(args: Array[String]) {
println(balance("{{ssss{{}}}}}".toList))
}
def balance(chars: List[Char]): Boolean = {
val openParentheses : List[Char] = List('(','{','[')
val matchingParentheses = Map(
'}'-> '{',
']'->'[',
')'->'(');
val openParenthesesFound: Stack[Char] = Stack[Char]()
for (letter <- chars) {
if (openParentheses.contains(letter)) openParenthesesFound.push(letter)
else if (matchingParentheses.contains(letter)) {
if (openParenthesesFound.isEmpty || !openParenthesesFound.head.equals(matchingParentheses(letter))) return false
else
openParenthesesFound.pop
}
}
if (openParenthesesFound.nonEmpty) false else true
}
}
然而,在行
if (openParenthesesFound.isEmpty || !openParenthesesFound.head.equals(matchingParentheses(letter))) return false
else
openParenthesesFound.pop
如果按照IntellijIdea的建议删除“返回”,程序将失败并且我得错了答案:是的。
任何人都可以帮我解释为什么会这样吗?我可能错过了一些东西。 此外,是否有人有更好的解决方案来完成这类任务?
非常感谢你的帮助, 乔瓦尼
答案 0 :(得分:2)
Intellij错了。显然,删除return语句会改变函数的逻辑。 或许,告诉你的意思是在scala中使用return语句通常是不受欢迎的。通常最好提出一个避免它的解决方案。实际上,可变状态也是如此......
这样的事情是其中一种可能性:
val parens = "{[(" zip "}])" toMap
object OpenP {
def unapply(c: Char) = parens.keys.find(_ == c)
}
object CloseP {
def unapply(c: Char) = parens.values.find(_ == c)
}
@tailrec
def balanced(s: List[Char], ps: List[Char] = Nil): Boolean = (ps, s) match {
case (stack, Nil) => stack.isEmpty
case (p :: stack, CloseP(c) :: tail) => c == parens(p) && balanced(tail, stack)
case (stack, OpenP(p) :: tail) => balanced(tail, p :: stack)
case (stack, c :: tail) => balanced(tail, stack)
}
答案 1 :(得分:1)
您的代码流量将发生重大变化,具体取决于您是否在return
理解中使用for
。
如果您使用return
,那么当您第一次在该代码路径中结束时,balance
方法将以false
退出,这似乎是您想要的(返回{{1}当你遇到第一个不匹配的括号时,因为你要求不存在。)
如果您不使用false
,则只有包含return
块的内容将评估为false(请记住,Scala中的所有内容都是表达式),而不是退出整个方法。由于你没有分配它或检查它,你的检查实际上几乎没有任何东西,你将循环整个过程,最后一个语句返回if-else
。因此,如果您想以这种方式解决此问题,则需要true
。
但是,Scala鼓励函数编程风格没有可变状态(例如你的return
)。解决这个问题的最简单方法可能是递归并使用累加器来存储中间括号堆栈 - 这样你就不需要可变状态(Stack
s或可变集合)。并且您避免使用显式var
(这是鼓励的 - 也可能是您的IDE通知您使用它的原因),因为方法隐式返回其最后一个语句作为其值,这通常很容易实现递归方法。