F#开发一个函数,计算只包含“叶子”的分支数

时间:2014-02-08 13:59:00

标签: f# functional-programming

我有表达式 - (cos(9**5)-cos(8*5))*(sin(3+1)**exp(6*6))。 我在类型 -

中呈现此表达式
type common = 
         Exp of common*common 
       | Sin of common
       | Cos of common
       | Bin of common*string*common
       | Digit of float
       | Exponent of common

let expr = Bin(Bin(Cos(Exp(Digit(9.0),Digit(5.0))),"-",Cos(Bin(Digit(8.0),"*",Digit(5.0)))),"*",Exp(Sin(Bin(Digit(3.0),"+",Digit(1.0))),Exponent(Bin(Digit(6.0),"*",Digit(6.0)))));

我有计算表达式的函数 -

let rec evalf com = 
        match com with
        Digit(x) -> x
        |Exp(d1,d2) -> let dig1 = evalf(d1)
                       let dig2 = evalf(d2)
                       System.Math.Pow(dig1,dig2)
        |Sin(d) -> let dig = evalf(d) 
                   System.Math.Sin(dig)
        |Cos(d) -> let dig = evalf(d) 
                   System.Math.Cos(dig)
        |Exponent(d) -> let dig = evalf(d) 
                        System.Math.Exp(dig)
        |Bin(d1,op,d2) -> let dig1 = evalf(d1)
                          let dig2 = evalf(d2)
                          match op with
                          | "*" -> dig1*dig2
                          | "+" -> dig1+dig2
                          | "-" -> dig1-dig2

我需要开发一个函数来计算仅包含“叶子”的分支数。请帮忙。

1 个答案:

答案 0 :(得分:2)

如果将“叶子”定义为数字,那么要计算仅包含“叶子”的分支数,您需要计算仅引用数字的表达式数。

这可以通过类似于evalf的递归函数来实现,对于只有“叶子”/数字的分支返回1,对非数字情况递归,例如。

let rec count expr =
  match expr with
  | Expr(Digit(_),Digit(_) -> 1
  | Expr(d1,d2) -> count d1 + count d2
  | Sin(Digit(_)) -> 1
  | Sin(d) -> count d
  // ... for all cases

可以使用类似的技术来简化表达式树,例如,可以匹配2个数字上的二进制运算(Bin)并将其简化为单个数字。这可以用作例如编译器优化步骤。