我有表达式 - (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
我需要开发一个函数来计算仅包含“叶子”的分支数。请帮忙。
答案 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
)并将其简化为单个数字。这可以用作例如编译器优化步骤。