鉴于我有3个双打:
double a = 1.0;
double b = 2.0;
double c = 3.0;
如何使用以下操作生成所有可能的数学方程式:
+
*
^2
sqrt()
()
示例如下:
生成每个等式的字符串
使用本机roslyn
编译器执行字符串,或创建自己的逻辑执行实现,或使用ncalc
第一个选项是最好的,但它不是最快的。所以我的问题是 - 如何在example
部分中生成字符串,或者如果有更好的方法解决这个问题 - 我想听听这些想法。
答案 0 :(得分:1)
我在表达树和无上下文语法方面考虑这个问题。你可以说像
EXPRESSION ::=
1 | 2 | 3
| ( EXPRESSION )+( EXPRESSION )
| ( EXPRESSION )*( EXPRESSION )
| ( EXPRESSION )^2
| sqrt( EXPRESSION )
;
这对括号有点过分了,所以如果你关心漂亮的字符串,你可能想要在后处理步骤中清理多余的parens,或者使用一些更精细的语法与多个非终端来正确处理它们。
您可以从三个终端规则的表达式树开始,即您的三个常量。然后,您可以考虑每个递归规则并插入您的常量来代替非终端。所以你生成1 + 1,1 + 2,1 + 3,2 + 1,2 + 2,2 + 3 + 3 + 1,3 + 2,3 + 3,(1)*(1) ,......像
这样的东西for op in [plus, times]:
for lhs in expressions:
for rhs in expressions:
new_expressions.append(binaryop(lhs, op, rhs))
for op in [square, sqrt]:
for arg in expressions:
new_expressions.append(unaryop(op, arg))
然后在每个这样的循环之后,你将不得不使用新发现的表达式来扩展表达式集。对于下一轮,您将尝试确保在最后一轮中生成至少一个操作数。对于二进制操作,另一个可能更旧。
如果每个可能的值只使用一个公式,事情就会变得更加可行。因此,一旦你发现1 + 3可以用作4的表达式,你就不会做2 + 2和2 * 2以及2 ^ 2,依此类推,因为表达4的一种方式就足够了。取决于申请。