我正在努力实现Martin Odersky的CourseRa Scala课程中显示的示例,尝试使用适当的括号显示持有Sums / Prods的表达式。我提出了以下解决方案:
package expressions
trait Expr {
def eval : Int = {
this match {
case Number(n) => n
case Sum(e1,e2) => e1.eval + e2.eval
}
}
//def show( exp : Expr) : String
}
case class Number(n:Int) extends Expr
case class Sum(e1: Expr, e2: Expr) extends Expr
case class Prod(e1 : Expr, e2 : Expr) extends Expr
case class Var(x:Char) extends Expr
object testExpr {
def show(exp : Expr) : String = {
exp match {
case Number(x) => x.toString()
case Sum(e1, e2) => show(e1) + "+" + show(e2)
case Prod(e1,e2) =>
val st1 = e1 match {
case Sum(a,b) => "(" + show(Sum(a,b)) + ")"
case _ => show(e1)
}
val st2 = e2 match {
case Sum(a,b) => "(" + show(Sum(a,b)) + ")"
case _ => show(e2)
}
st1 + "*" + st2
case Var(x) => x.toString
}
}
}
object test extends App{
println(testExpr.show(Sum(Number(1),Number(2))))
println(Sum(Number(1),Number(3)).eval)
println(testExpr.show(Sum(Number(2),Prod(Number(10),Var('x')))))
println(testExpr.show(Sum(Prod(Number(2),Var('x')),Var('y'))))
println(testExpr.show(Prod(Sum(Number(2),Var('x')),Var('y'))))
println(testExpr.show(Prod(Sum(Number(2),Var('x')),Sum(Number(3),Var('y')))))
}
我决定放括号的方式绝对不是最佳解决方案。任何人都可以提出更好的解决方案来实现同样的目标。
谢谢和问候, Paromita
答案 0 :(得分:6)
与ParoTech和Val的有些相似,只是略有干扰:
def show(e: Expr): String = {
def paren(e:Expr) = {
e match {
case Sum(_, _) => "(" + show(e) + ")"
case _ => show(e)
}
}
e match {
case Number(n) => n.toString
case Var(s) => s
case Sum(e1, e2) => show(e1) + " + " + show(e2)
case Prod(e1, e2) => paren(e1) + " * " + paren(e2)
}
}
答案 1 :(得分:5)
case Variable(name) => name
case Product(e1, e2) => "%s * %s".format(
e1 match {
case Sum(_, _) => "(%s)".format(show(e1))
case _ => show(e1)
},
e2 match {
case Sum(_, _) => "(%s)".format(show(e2))
case _ => show(e2)
}
)
将使用元组匹配进一步重写为
case Product(e1, e2) =>
val format = (e1, e2) match {
case (Sum(_, _), _) => "(%s) * %s"
case (_, Sum(_, _)) => "%s * (%s)"
case (_, _) => "%s * %s"
}
format.format(show(e1), show(e2))
答案 2 :(得分:2)
我猜这个假设的解决方案是前缀
case Prod(l, r) => show(l) + "*" + show(r)
带
case Prod(Sum(sl, sr), r) => "(" + show(sl) + " + " + show(sr) + ")" + "*" + show(r)
如此处所示https://github.com/glebd/scala-course/blob/master/workspace/hello-project/src/week4/exprs.sc
结果代码是
def show(e: Expr): String = e match {
case Number(n) => n.toString
case Var(v) => v
case Prod(Sum(e1, e2), Sum(e3, e4)) => "(" + show(e1) + "+" + show(e2) + ")*(" + show(e3) + "+" + show(e4) + ")"
case Prod(Sum(e1, e2), e3) => "(" + show(e1) + "+" + show(e2) + ")*" + show(e3)
case Prod(e1, Sum(e2, e3)) => show(e1) + "*(" + show(e2) + "+" + show(e3) + ")"
case Sum(e1, e2) => show(e1) + "+" + show(e2)
case Prod(e1, e2) => show(e1) + "*" + show(e2)
}
我不知道Krupennik的解决方案应该做什么。奥德斯基没有证明这样的结构。但是这个解决方案揭示了Krupennik正在做的事情。