我只是愚弄,奇怪地发现在一个简单的递归函数中解析嵌套括号有点棘手.
例如,如果该计划的目的是查找用户的详细信息,它可能会从{{name surname} age}到{Bob Builder age}再到Bob Builder 20.
这是一个迷你程序,用于对大括号中的总计进行求和,以演示该概念.
// Parses string recursively by eliminating brackets
def parse(s: String): String = {
if (!s.contains("{")) s
else {
parse(resolvePair(s))
}
}
// Sums one pair and returns the string, starting at deepest nested pair
// e.g.
// {2+10} lollies and {3+{4+5}} peanuts
// should return:
// {2+10} lollies and {3+9} peanuts
def resolvePair(s: String): String = {
??? // Replace the deepest nested pair with it's sumString result
}
// Sums values in a string, returning the result as a string
// e.g. sumString("3+8") returns "11"
def sumString(s: String): String = {
val v = s.split("\\+")
v.foldLeft(0)(_.toInt + _.toInt).toString
}
// Should return "12 lollies and 12 peanuts"
parse("{2+10} lollies and {3+{4+5}} peanuts")
Run Code Online (Sandbox Code Playgroud)
任何可以取代它的代码的想法???都会很棒.这主要是出于好奇,我正在寻找这个问题的优雅解决方案.
解析器组合器可以处理这种情况:
import scala.util.parsing.combinator.RegexParsers
object BraceParser extends RegexParsers {
override def skipWhitespace = false
def number = """\d+""".r ^^ { _.toInt }
def sum: Parser[Int] = "{" ~> (number | sum) ~ "+" ~ (number | sum) <~ "}" ^^ {
case x ~ "+" ~ y => x + y
}
def text = """[^{}]+""".r
def chunk = sum ^^ {_.toString } | text
def chunks = rep1(chunk) ^^ {_.mkString} | ""
def apply(input: String): String = parseAll(chunks, input) match {
case Success(result, _) => result
case failure: NoSuccess => scala.sys.error(failure.msg)
}
}
Run Code Online (Sandbox Code Playgroud)
然后:
BraceParser("{2+10} lollies and {3+{4+5}} peanuts")
//> res0: String = 12 lollies and 12 peanuts
Run Code Online (Sandbox Code Playgroud)
在熟悉解析器组合器之前有一些投资,但我认为这是值得的.
为了帮助您破译上面的语法:
Parser[String].^^运营商允许的功能应用到解析的元素
Parser[String]成Parser[Int]做^^ {_.toInt}Parser[T].^^(f)相当于Parser[T].map(f)~,~>并且<~需要一些输入为以一定的顺序
~>和<~输入的一侧退出的结果的case a ~ b允许模式相匹配的结果(p ~ q) ^^ { case a ~ b => f(a, b) }相当于for (a <- p; b <- q) yield (f(a, b)) (p <~ q) ^^ f 相当于 for (a <- p; _ <- q) yield f(a)rep1 是一个或多个元素的重复| 尝试将输入与其左侧的解析器匹配,如果失败,则会尝试右侧的解析器| 归档时间: |
|
| 查看次数: |
934 次 |
| 最近记录: |