1

分配規則を使用してこの数式を単純化する scala プログラムを書きたいと思います。

a*b+a*c = a(b+c)

この例を解決するために、次のコードをすぐに書きました。

object Test {

  sealed abstract class Expr

  case class Var(name: String) extends Expr

  case class BinOp(operator: String, left: Expr, right: Expr) extends Expr


  def main(args: Array[String]) {
    val expr = BinOp("+", BinOp("*", Var("a"), Var("b")), BinOp("*", Var("a"), Var("c")))
    println(simplify(expr)) //outputs "a(b + c)"
  }

  def simplify(expr: Expr) : String = expr match {
    case BinOp("+", BinOp("*", Var(x), Var(a)), BinOp("*", Var(y), Var(b))) if (x == y) => "" + x + "*(" + a + " + " + b + ")"
    case _ => "" //no matter for the test since I test the first case statically
  }

}

これを達成するためのより良い方法はありますか?

組み合わせごとにケースを複製せずにオペランドの順序を管理する最良の方法は何ですか (醜いでしょう...)? 実際、これらの表現はどうでしょうか。

a*b+a*c = a(b+c)

a*b+c*a = a(b+c)

b*a+a*c = a(b+c)

b*a+c*a = a(b+c)

4

1 に答える 1

1

Exprが交換法則を保持する場合、それは

def simplify(expr: Expr) : String = expr match {
  case expr @ BinOp("+", BinOp("*", Var(x), Var(a)), BinOp("*", Var(y), Var(b))) => {
    def another(that: String) = {
      Seq((x, a), (a, x)) find (_._1 == that) map (_._2)
    }

    val byY = another(y).map(z => BinOp("+", Var(y), BinOp("*", Var(z), Var(b)))) // combine by y
    val byB = another(b).map(z => BinOp("+", Var(b), BinOp("*", Var(z), Var(y)))) // combine by b
    (byY orElse byB getOrElse expr).toString
  }
  case _ => "" //no matter for the test since I test the first case statically
}

byYbyB同じ構造を持っています。これは最善ではありません。コードの一部を再利用する可能性があります。:P

于 2012-12-20T11:28:30.120 に答える